轮换+区间+收集果子
来源:互联网 发布:mac工商银行网银控件 编辑:程序博客网 时间:2024/05/16 04:44
理解了题意就很容易模拟了。
从后向前,然后括号里面的不是位置,而是数。
#include <cstdio>#include <iostream>#include <vector>using namespace std;int w[99999];int z[1001][1001];int w2[99999];int main(){ freopen("rotate.in","r",stdin); freopen("rotate.out","w",stdout); int n,q,k; scanf("%d%d%d",&n,&q,&k); for(int i=1;i<=n;i++) w[i]=i; for(int i=1;i<=q;i++) { int m; scanf("%d",&m); z[i][0]=m; for(int j=1,x;j<=m;j++) scanf("%d",&z[i][j]); } for(int i=q;i>=1;i--) { int tmp=w[z[i][z[i][0]]]; for(int j=z[i][0];j>1;j--) w[z[i][j]]=w[z[i][j-1]]; w[z[i][1]]=tmp; } for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) if(w[j]==i) { printf("%d ",j); break; } } /*for(int j=1;j<=n;j++) printf("%d ",w[j]);*/}
ST表处理
先处理出i->i+2^j的or和and
方法1:二分答案
用二分优化i->j j走的过程,直接找出一段连续区间相同的,然后直接跳。
方法2:倍增找答案
对于一个i
直接倍增找i最近能满足条件的j和最远的j
方法1:二分(极端数据肯定T)
#include <cstdio>#include <iostream>#include <vector>#include <cmath>using namespace std;const int mod=1e9+7;int ana[110000][21],ord[110000][21];int q[110000]; int get_and(int l,int r){ int len=(r-l)+1; int t=log2(len); return ana[l][t]&ana[r-(1<<t)+1][t]; }int get_or(int l,int r){ int len=(r-l)+1; int t=log2(len); return ord[l][t]|ord[r-(1<<t)+1][t]; }int main(){ freopen("range.in","r",stdin); //freopen("range.out","w",stdout); int n,a,b,c,d; scanf("%d%d%d%d%d",&n,&a,&b,&c,&d); for(int i=1;i<=n;i++) scanf("%d",&q[i]),ana[i][0]=q[i],ord[i][0]=q[i]; for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) if(i+(1<<j)-1<=n) { ana[i][j]=ana[i][j-1]&ana[i+(1<<j-1)][j-1]; ord[i][j]=ord[i][j-1]|ord[i+(1<<j-1)][j-1]; } long long cnt=0; for(int i=1;i<=n;i++) { int andx=q[i],orx=q[i]; for(int j=i;j<=n;j++) { int l=j,r=n+1;//起点终点 int flag=1; andx=get_and(i,j); orx=get_or(i,j); if(a<=andx&&b>=andx&&c<=orx&&d>=orx) flag=0; //if(flag) continue; int ans=0; while(l<=r) { int mid=(l+r)/2; if(andx&&get_and(i,mid)==andx&&orx&&get_or(i,mid)==orx) l=mid+1,ans=mid; else r=mid-1; } if(ans) { if(a<=andx&&b>=andx&&c<=orx&&d>=orx) cnt+=(ans-j+1)%mod; j=ans; } else break; } } printf("%lld\n",cnt%mod);}
方法2:倍增
#include <cstdio>#include <iostream>#include <vector>#include <cmath>using namespace std;const int mod=1e9+7;int ana[110000][21],ord[110000][21];int q[110000]; int get_and(int l,int r){ int len=(r-l)+1; int t=log2(len); return ana[l][t]&ana[r-(1<<t)+1][t]; }int get_or(int l,int r){ int len=(r-l)+1; int t=log2(len); return ord[l][t]|ord[r-(1<<t)+1][t]; }int main(){ freopen("range.in","r",stdin); //freopen("range.out","w",stdout); int n,a,b,c,d; scanf("%d%d%d%d%d",&n,&a,&b,&c,&d); for(int i=1;i<=n;i++) scanf("%d",&q[i]),ana[i][0]=q[i],ord[i][0]=q[i]; for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) if(i+(1<<j)-1<=n) { ana[i][j]=ana[i][j-1]&ana[i+(1<<j-1)][j-1]; ord[i][j]=ord[i][j-1]|ord[i+(1<<j-1)][j-1]; } long long cnt=0; for(int i=1;i<=n;i++) { int tmp1=i,tmp2,s1=(1<<19)-1,s2=0; if(ana[i][0]<a||ord[i][0]>d) continue; for(int k=18;k>=0;k--) if(tmp1+(1<<k)-1<=n) if(((ana[tmp1][k]&s1)>b)||((ord[tmp1][k]|s2)<c)) s1&=ana[tmp1][k],s2|=ord[tmp1][k],tmp1+=(1<<k); tmp2=tmp1; for(int k=18;k>=0;k--) if(tmp1+(1<<k)-1<=n) if(((ana[tmp1][k]&s1)>=a)&&((ord[tmp1][k]|s2)<=d)) s1&=ana[tmp1][k],s2|=ord[tmp1][k],tmp1+=(1<<k); tmp1--; if(tmp1-tmp2>=1) cnt+=(tmp1-tmp2+1); } printf("%lld\n",cnt%mod);}
收集果子,还没做。。。
阅读全文
1 0
- 轮换+区间+收集果子
- 轮换
- 轮换
- 图片轮换
- 轮换广告
- 图片轮换
- 字符串轮换
- 图片轮换
- 图片轮换
- 图片轮换
- 半残 -- 轮换
- 图片轮换
- 水晶果子
- 新鲜果子
- 合并果子
- 合并果子
- 合并果子
- 合并果子
- 如何将寸照背景成功换底
- Ajax异步添加数据(SSM框架)
- CSDN如何转载别人的文章
- python 使用matplotlib绘图中文显示成框框解决办法
- spring-boot
- 轮换+区间+收集果子
- 蓝牙协议分析(6)_BLE地址类型
- 通达OA二次开发 小飞鱼OA工资上传数据模块开发(图文)
- Android使用OpenCV合成双目裸眼3D图片(推荐Native方法)
- ES6之箭头函数(Arrow Function)
- Hibernate和struts2的整合代码截图
- Maven工程的多模块项目、项目与项目之间的引用
- Niagara在国内为什么没有发展起来?
- MySQL 触发器、存储过程、游标