当前位置:   article > 正文

Codeforces Round 745 (Div. 2)(C:前缀和+滑动窗口,E:位运算加分块)

Codeforces Round 745 (Div. 2)(C:前缀和+滑动窗口,E:位运算加分块)

Dashboard - Codeforces Round 745 (Div. 2) - Codeforces

A:

答案就是2n!/2,

对于当前满足有k个合法下标的排列,就是一个n-k个不合法的下标的排列,

所以每一个合法排列都相反的存在一个

对称性

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1e6+10,mod=1e9+7;
  4. #define int long long
  5. int n,m;
  6. int f[N];
  7. void solve()
  8. {
  9. cin>>n;
  10. int res=1;
  11. for(int i=1;i<=2*n;i++)
  12. {
  13. if(i==2) continue;
  14. res=res*i%mod;
  15. }
  16. cout<<res%mod<<"\n";
  17. }
  18. signed main()
  19. {
  20. cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
  21. int t=1;
  22. cin>>t;
  23. while(t--) solve();
  24. }

B:

可以先手完一下,

对于一个n

如果m<n-1,那么这个图直接就不连通了,直接false

如果m==(n-1)*n/2,那么这个图就是完全无向连通图,直径最长是1

在这个中间,直径最长是2,直接在1点用n-1条边连其他点

然后特判啥的就行

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 1e6+10,mod=1e9+7;
  4. #define int long long
  5. int n,m,k;
  6. int f[N];
  7. void solve()
  8. {
  9. cin>>n>>m>>k;
  10. if(k<=1||m>n*(n-1)/2||m<n-1)
  11. {
  12. cout<<"NO\n";
  13. return ;
  14. }
  15. if(n==1&&m==0)
  16. {
  17. cout<<"YES\n";return ;
  18. }
  19. if(k==2||k==3&&m!=n*(n-1)/2){
  20. cout<<"NO\n";return ;
  21. }
  22. cout<<"YES\n";
  23. }
  24. signed main()
  25. {
  26. cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
  27. int t=1;
  28. cin>>t;
  29. while(t--) solve();
  30. }

C:

这个题好像蓝桥杯之前写过,枚举三条线,然后滑动窗口来着

这个题基本一模一样

然后想上下两条线

先想一个问题

因为枚举的是D,那么D那条线答案是不用管的(因为我们枚举的第三条就是这个嘛),

然后想U,如果某个U到D和U+x到D,相同答案,那么选谁呢,其实都一样,如果D往下移,那么他们要加的公共部分都是一样的就是g[D][L],g[D][R],和D那条线,这个都是要加的,

如果要求某个[1,D-4]的线到D最小就行

快速统计矩阵的0,1用二维前缀和即可

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 410+10,mod=1e9+7;
  4. #define int long long
  5. int n,m,k;
  6. char g[N][N];
  7. int b[N][N];;
  8. int s[N][N];
  9. int row[N][N];
  10. int col[N][N];
  11. int val(int x1,int y1,int x2,int y2){
  12. //cin>>x1>>y1>>x2>>y2;
  13. return s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1];
  14. }
  15. int getrow(int i,int x,int y){
  16. return row[i][y]-row[i][x-1];
  17. }
  18. int getcol(int i,int x,int y){
  19. return col[i][y]-col[i][x-1];
  20. }
  21. void solve()
  22. {
  23. cin>>n>>m;
  24. for(int i=1;i<=n;i++){
  25. for(int j=1;j<=m;j++){
  26. cin>>g[i][j];
  27. s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+(g[i][j]-'0');
  28. row[i][j]=row[i][j-1]+(g[i][j]-'0');
  29. col[j][i]=col[j][i-1]+(g[i][j]-'0');
  30. b[i][j]=g[i][j]-'0';
  31. }
  32. }
  33. int res=n*m;
  34. for(int L=1;L<=m;L++){
  35. for(int R=L+3;R<=m;R++)
  36. {
  37. int tmp=n*m;
  38. for(int D=5;D<=n;D++){
  39. if(b[D-1][L]==0) tmp++;
  40. if(b[D-1][R]==0) tmp++;
  41. tmp+=val(D-1,L+1,D-1,R-1);
  42. int now=(R-L-1)-val(D-4,L+1,D-4,R-1)+3-val(D-3,L,D-1,L)+3-val(D-3,R,D-1,R)+val(D-3,L+1,D-1,R-1);
  43. tmp=min(tmp,now);
  44. res=min(res,tmp+R-L-1-val(D,L+1,D,R-1));
  45. }
  46. }
  47. }
  48. cout<<res<<"\n";
  49. }
  50. signed main()
  51. {
  52. cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
  53. int t=1;
  54. cin>>t;
  55. while(t--) solve();
  56. }

E:

如果一个车车进来了

那么

工作区间有:[st,st+x-1],[st+x+y,st+x+y+x]....

休息区间有:[st+x,st+x+y-1],[st+x+y+x,st+x+y+x+y-1]....

所以在%(x+y)这个区间在休息区间那么就加一

差分,如果x+y>500,那么只需要400次就可以遍历完所以需要修改的点,

如果x+y<500,那么维护一个区间大小(x+y)去增加这个i%(x+y)点,

即维护一个 x+y【0,500】里面每个余数相同的点

分块即可

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N = 2e5+10,mod=1e9+7;
  4. int n,m,k;
  5. int x[N],y[N];
  6. int a[N];
  7. int s[N];
  8. int thre,ans;
  9. int cnt[510][510];
  10. void update(int st,int k,int v){
  11. int aa=x[k]+y[k];
  12. int *c=cnt[aa];
  13. int l=(st+x[k])%aa;
  14. int r=(st-1)%aa;
  15. if(l<=r){
  16. for(int i=l;i<=r;i++) c[i]+=v;
  17. }
  18. else{
  19. for(int i=0;i<=r;i++) c[i]+=v;
  20. for(int i=l;i<aa;i++) c[i]+=v;
  21. }
  22. }
  23. int query(int x){
  24. int res=0;
  25. for(int i=2;i<=thre;i++){
  26. res+=cnt[i][x%i];
  27. }
  28. return res;
  29. }
  30. void solve()
  31. {
  32. cin>>n>>m;
  33. thre=sqrt(m);
  34. for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
  35. for(int i=1;i<=m;i++){
  36. int op,k;
  37. cin>>op>>k;
  38. if(op==1){
  39. int aa=x[k]+y[k];
  40. if(aa>thre){
  41. for(int j=i+x[k];j<=m;j+=aa){
  42. a[j]++;
  43. if(j+y[k]<=m) a[j+y[k]]--;
  44. }
  45. }
  46. else update(i,k,1);
  47. s[k]=i;
  48. }
  49. else{
  50. int aa=x[k]+y[k];
  51. if(aa>thre){
  52. for(int j=s[k]+x[k];j<=m;j+=aa){
  53. a[j]--;
  54. if(j<=i-1) ans--;
  55. if(j+y[k]<=i-1) ans++;
  56. if(j+y[k]<=m) a[j+y[k]]++;
  57. }
  58. }
  59. else update(s[k],k,-1);
  60. }
  61. ans+=a[i];
  62. cout<<ans+query(i)<<"\n";
  63. }
  64. }
  65. signed main()
  66. {
  67. cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
  68. int t=1;
  69. //cin>>t;
  70. while(t--) solve();
  71. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/72476
推荐阅读
相关标签
  

闽ICP备14008679号