boom…
100→50
(1)blash
队列操作题,自带双指针
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(long long x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 1111111
int a,n,p2,p3,sze;
long long tmp2,tmp3,que[stan],tmp;
signed main(){
while(scanf("%d%d",&a,&n)!=EOF){
sze=2;
que[1]=a;
p2=1;p3=1;
while(sze<=n){
tmp2=que[p2]*2+1;
tmp3=que[p3]*3+1;
tmp=min(tmp2,tmp3);
if(tmp2else
++p3;
if(tmp==que[sze-1]) continue;
que[sze++]=tmp;
}
write(que[n]);
puts("");
}
return 0;
}
(2)序列操作
二分判定性问题
其实因为 h[i] 小于 10000 也可以桶操作
不过不要手贱乱减
桶操作版
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(int x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 1111111
#define sten 11111
int n,m,h[stan],c[stan],sze[sten],tmp[sten],pos;
signed main(){
n=read();m=read();
for(int i=1;i<=n;++i)
h[i]=read();
sort(h+1,h+n+1);
for(int i=1;i<=m;++i)
c[i]=read();
if(m<=1000&&n<=1000){
for(int i=1;i<=m;++i){
for(int j=n;j>n-c[i];--j)
if(h[j]==0){
write(i-1);
return 0;
}else --h[j];
sort(h+1,h+n+1);
}
write(m);
return 0;
}else{
for(register int i=1;i<=n;++i){
++sze[h[i]];pos=max(h[i],pos);
}
for(register int i=1;i<=m;++i){
for(register int j=pos;j;--j){
if(sze[j]>=c[i]){
sze[j]=sze[j]-c[i];
sze[j-1]+=c[i];
sze[j]+=tmp[j];
tmp[j]=0;
c[i]=0;
break;
}else if(sze[j]>0){
c[i]-=sze[j];
tmp[j-1]=sze[j];
sze[j]=tmp[j];
tmp[j]=0;
}else if(tmp[j]){
sze[j]=tmp[j];
tmp[j]=0;
}
}
if(c[i]>0){
write(i-1);
return 0;
}
}
write(m);
return 0;
}
}
巧妙的二分
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(long long x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
#define stan 1111111
long long sum,val,cnt[stan],h[stan];
int n,m,c[stan];
bool check(int k){
for(int i=0;i<=n+1;++i)
cnt[i]=0;
sum=0;val=0;
for(int i=1;i<=k;++i){
if(c[i]>n) return false;
++cnt[c[i]];
sum+=c[i];
}
for(int i=n;i;--i)
cnt[i]+=cnt[i+1];
for(int i=1;i<=n;++i){
val+=min(cnt[i],h[i]);
if(h[i]1]+=cnt[i]-h[i];
}
return val==sum;
}
signed main(){
n=read();m=read();
for(int i=1;i<=n;++i)
h[i]=read();
sort(h+1,h+n+1);
reverse(h+1,h+n+1);
for(int i=1;i<=m;++i)
c[i]=read();
int l=0,r=m,ans=0;
while(l<=r){
int mid=l+r>>1;
if(check(mid)){
ans=mid;
l=mid+1;
}else r=mid-1;
}
write(ans);
return 0;
}
(3)序列操作
LCT
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
inline int read(){
int i=0,f=1;
char ch;
for(ch=getchar();!isdigit(ch);ch=getchar())
if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar())
i=(i<<3)+(i<<1)+(ch^48);
return i*f;
}
int buf[1024];
inline void write(long long x){
if(!x){putchar('0');return ;}
if(x<0){putchar('-');x=-x;}
while(x){buf[++buf[0]]=x%10,x/=10;}
while(buf[0]) putchar(buf[buf[0]--]+48);
return ;
}
using namespace std;
#define stan 111111
#define sten 222222
struct edge{
int x,y,k;
friend bool operator < (edge a,edge b){
return a.kint n,A,B,q;
struct query{
int v,id;
friend bool operator<(query a,query b){
return a.vint fath[stan];
struct node{
int s[2];
int id,val;
bool tag;
}tree[stan*2];
int val[stan*2];
int fa[stan*2];
long long ans[stan];
inline int getfa(int x){
return (fath[x]==x)?fath[x]:fath[x]=getfa(fath[x]);
}
void gettree(edge *e,int t){
for(int i=1;i<=n;++i)
fath[i]=i;
sort(e+1,e+1+t);
int u=0;
for(int i=1;i<=t;++i){
int x=e[i].x,y=e[i].y;
int fx=getfa(x),fy=getfa(y);
if (fx==fy)continue;
fath[fx]=fy;
e[++u]=e[i];
}
}
int key[stan];
int k;
void down(int x){
if(tree[x].tag){
swap(tree[x].s[0],tree[x].s[1]);
tree[tree[x].s[0]].tag^=1;
tree[tree[x].s[1]].tag^=1;
tree[x].tag=0;
}
return ;
}
void update(int x){
tree[x].val=val[x];tree[x].id=x;
if(tree[x].s[0]&&tree[tree[x].s[0]].val>tree[x].val)
tree[x].val=tree[tree[x].s[0]].val,tree[x].id=tree[tree[x].s[0]].id;
if(tree[x].s[1]&&tree[tree[x].s[1]].val>tree[x].val)
tree[x].val=tree[tree[x].s[1]].val,tree[x].id=tree[tree[x].s[1]].id;
return ;
}
int pd(int x){
if(x==tree[fa[x]].s[0])
return 0;
else if(x==tree[fa[x]].s[1])
return 1;
else return -1;
}
void rotate(int x){
int y=fa[x],z=fa[y];
int tx=pd(x),ty=pd(y);
if (ty!=-1)tree[z].s[ty]=x;
fa[x]=z;
if(tree[x].s[tx^1])
fa[tree[x].s[tx^1]]=y;
tree[y].s[tx]=tree[x].s[tx^1];
tree[x].s[tx^1]=y;
fa[y]=x;
update(y),update(x);
if (ty!=-1)update(z);
}
int sta[stan*2],tp;
void clear(int x){
tp=0;
for(;pd(x)!=-1;x=fa[x])
sta[++tp]=x;
sta[++tp]=x;
for(int i=tp;i;--i)
down(sta[i]);
return ;
}
void splay(int x){
clear(x);
for(;pd(x)!=-1;){
if (pd(fa[x])!=-1){
if(pd(x)==pd(fa[x])) rotate(fa[x]);
else rotate(x);
}
rotate(x);
}
return ;
}
void split(int x){
down(x);
if(!tree[x].s[1]) return;
tree[x].s[1]=0;
update(x);
return ;
}
void merge(int x,int y){
tree[x].s[1]=y;
update(x);
}
void access(int x){
splay(x),split(x);
for(;fa[x];x=fa[x]){
splay(fa[x]),split(fa[x]);
merge(fa[x],x);
}
}
void makeroot(int x){
access(x),splay(x);
tree[x].tag^=1;
}
signed main(){
n=read();A=read();B=read();q=read();
for(int i=1;i<=A;++i){
edgea[i].x=read();edgea[i].y=read();edgea[i].k=read();
}
for(int i=1;i<=B;++i){
edgeb[i].x=read();edgeb[i].y=read();edgeb[i].k=read();
}
gettree(edgea,A);
gettree(edgeb,B);
for(int i=1;i<=n;++i){
tree[i].val=val[i]=-999999999;
tree[i].id=i;
}
long long now=0;
for(int i=1;iint x=edgea[i].x,y=edgea[i].y;
makeroot(x),makeroot(y);
splay(x),splay(y);
fa[x]=fa[y]=n+i;
tree[n+i].val=val[n+i]=edgea[i].k;
tree[n+i].id=i;
now=now+edgea[i].k;
}
for(int i=1;iint x=edgeb[i].x,y=edgeb[i].y;
makeroot(x),access(y),splay(y);
int t=tree[y].id;
if(val[t]==-999999999) continue;
splay(t);
key[++k]=edgeb[i].k-val[t];
fa[tree[t].s[0]]=fa[tree[t].s[1]]=0;
makeroot(x),makeroot(y);
fa[y]=x;
}
for(int i=1;i<=q;++i){
que[i].v=read();
que[i].id=i;
}
sort(que+1,que+1+q);
sort(key+1,key+1+k);
int w=1;
for(int i=1;i<=q;++i){
while(w<=k&&key[w]<=que[i].v*2)now=now+key[w++];
ans[que[i].id]=now+1ll*que[i].v*(n-1-(w-1)*2);
}
for(int i=1;i<=q;++i){
write(ans[i]);
puts("");
}
return 0;
}