B
见面就想暴力,然后数据量直接劝退
题解说是莫队,确实,只要可以推出由S(i,j) 可以转移到 S(i,j+1),S(i,j-1),S(i-1,j),S(i+1,j),就符合用莫队的条件了
ps:顺便存一下组合数的模板,以前本弱竟然连这个都没存
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100100;
const int mod = 1000000007;
struct Node {
int l, r;
int Index;
};
int sq;
bool operator<(const Node &a, const Node &b) {
return a.r / sq == b.r / sq? a.l < b.l: a.r < b.r;
}
int T, n, m, l, r, Max;
int ans[N];
Node node[N];
int inv[N], pro[N], invpro[N];
void Init() {
inv[1] = 1;
for(int i = 2; i < N; ++i) {
inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
}
pro[0] = invpro[0] = 1;
for(int i = 1; i < N; ++i) {
pro[i] = (ll)pro[i - 1] * i % mod;
invpro[i] = (ll)invpro[i - 1] * inv[i] % mod;
}
}
int get_C(int n, int m) {
if(n < m) {
return 0;
}
return (ll)pro[n] * invpro[m] % mod * invpro[n - m] % mod;
}
int main() {
Max = 0;
Init();
scanf("%d", &T);
for(int i = 0; i < T; ++i) {
scanf("%d%d", &node[i].r, &node[i].l);
node[i].Index = i;
Max = max(Max, node[i].r);
}
sq = sqrt(Max);
sort(node, node + T);
l = 1;
r = 0;
ll tmp = 1;
ll ttmp;
for(int i = 0; i < T; ++i) {
while(r < node[i].r) {
ttmp = tmp + tmp;
if(ttmp >= mod) {
ttmp -= mod;
}
tmp = ttmp - get_C(r, l);
if(tmp < 0) {
tmp += mod;
}
++r;
}
while(l > node[i].l) {
tmp = tmp - get_C(r, l);
if(tmp < 0) {
tmp += mod;
}
--l;
}
while(r > node[i].r) {
ttmp = tmp + get_C(r - 1, l);
if(ttmp >= mod) {
ttmp -= mod;
}
tmp = (ttmp * inv[2]) % mod;
--r;
}
while(l < node[i].l) {
tmp = tmp + get_C(r, l + 1);
if(tmp >= mod) {
tmp -= mod;
}
++l;
}
ans[node[i].Index] = tmp;
}
for(int i = 0; i < T; ++i) {
printf("%d\n", ans[i]);
}
return 0;
}
D
水水就过了。既没什么要补的思维,又没什么要点的技能树。或许需要练练阅读理解??
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int T, n, m;
ll a[110], x, y;
int main(){
scanf("%d", &T);
while(T --){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i ++){
scanf("%lld %lld", &x, &y);
a[i] = x + y;
}
sort(a + 1, a + 1 + n);
ll ans = 0, tot = 1;
while(ans + 1 <= n && tot * a[ans + 1] <= m){
ans ++;
tot *= a[ans];
}
printf("%lld\n", ans);
}
return 0;
}
E
遇事不决先打表,然后就可以发现它是以2L为循环节的,然后就是二维前缀和的一些操作
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100 + 100;
int T, n, q;
int a[N];
ll num[N][N];
ll Sum(int x, int y) {
if(x < 0 || y < 0) {
return 0;
}
int nn = n << 1;
ll ret = num[nn - 1][nn - 1] * ((x + 1) / nn) * ((y + 1) / nn);
int xx = x % nn;
int yy = y % nn;
if(xx != nn - 1) {
ret += num[xx][nn - 1] * ((y + 1) / nn);
}
if(yy != nn - 1) {
ret += num[nn - 1][yy] * ((x + 1) / nn);
}
if(xx != nn - 1 && yy != nn - 1) {
ret += num[xx][yy];
}
return ret;
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; ++i) {
scanf("%d", &a[i]);
}
int Index = 0;
for(int i = 0; i < N; ++i) {
for(int j = 0; j <= i; ++j) {
num[j][i - j] = a[Index];
Index = (Index + 1) % n;
}
}
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
if(i != 0) {
num[i][j] += num[i - 1][j];
}
if(j != 0) {
num[i][j] += num[i][j - 1];
}
if(i != 0 && j != 0) {
num[i][j] -= num[i - 1][j - 1];
}
}
}
scanf("%d", &q);
int x1, x2, y1, y2;
while(q--) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
ll ans = Sum(x2, y2) + Sum(x1 - 1, y1 - 1);
ans -= Sum(x2, y1 - 1) + Sum(x1 - 1, y2);
printf("%I64d\n", ans);
}
}
return 0;
}
J
耿直的搜索,先增加列标,列标到最值后增大行标列标归零
#include<algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <vector>
#include <bitset>
#include <queue>
#include <map>
#include <set>
using namespace std;
char s[16][16],w[16][16];
int Ans;
void Rot(int a,int b)
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
w[j][3-i]=s[a+i][b+j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
s[a+i][b+j]=w[i][j];
}
int tot,vis[16];
bool check(int a,int b)
{
for(int i=a;i<a+4;i++)
{
tot++;
for(int j=0;j<b+4;j++)
{
if(vis[s[i][j]]==tot)
return 0;
vis[s[i][j]]=tot;
}
}
for(int i=b;i<b+4;i++)
{
tot++;
for(int j=0;j<a+4;j++)
{
if(vis[s[j][i]]==tot)
return 0;
vis[s[j][i]]=tot;
}
}
return 1;
}
void dfs(int i,int j,int k)
{
if(i==4)
{
Ans=min(Ans,k);return;
}
if(k>=Ans)
return;
if(j==4)
return dfs(i+1,0,k);
for(int t=0;t<4;t++)
{
if(check(i*4,j*4))
dfs(i,j+1,k+t);
Rot(i*4,j*4);
}
}
void solve()
{
for(int i=0;i<16;i++)
scanf(" %s",s[i]);
for(int i=0;i<16;i++)
for(int j=0;j<16;j++)
if(s[i][j]<='9')
s[i][j]-='0';
else
s[i][j]=s[i][j]-'A'+10;
Ans=1000;dfs(0,0,0);
cout<<Ans<<endl;
}
int main()
{
int t;cin>>t;
while(t--)
solve();
return 0;
}
K
这一场真是考验代码能力的一场,咕咕咕
#include<algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <vector>
#include <bitset>
#include <queue>
#include <map>
#include <set>
using namespace std;
char s[1005];
int n;
bool check()
{
for(int i=1;i<n;i++)
if((s[i]=='+'||s[i]=='*')&&(s[i+1]=='+'||s[i+1]=='*'))
return 0;
for(int i=1;i<n;i++)
if(s[i]=='0'&&!(s[i-1]>='0'&&s[i-1]<='9')&&(s[i+1]>='0'&&s[i+1]<='9'))
return 0;
if(s[1]=='+'||s[1]=='*'||s[n]=='+'||s[n]=='*')
return 0;
return 1;
}
void solve()
{
scanf(" %s",s+1);n=strlen(s+1);
for(int i=1;i<=n;i++)
if(s[i]=='0'&&!(s[i-1]>='0'&&s[i-1]<='9')&&s[i+1]=='?')
s[i+1]='+';
else if(s[i]=='?')
s[i]='1';
if(check())
puts(s+1);
else
puts("IMPOSSIBLE");
}
int main()
{
int t;cin>>t;
while(t--)
solve();
return 0;
}
L
sqrt(x+y) < sqrt(x) + sqrt(y)
#include <bits/stdc++.h>
using namespace std;
double a[100100];
int main(){
int t;
scanf("%d", &t);
while(t --){
int n;
cin >> n;
for(int i = 1; i <= n; i ++)
scanf("%lf", &a[i]);
int ans = sqrt(abs(a[1] - a[n]));
printf("%d\n", ans);
}
return 0;
}