3
7
2016
0

[BZOJ1503] [NOI2004]郁闷的出纳员

好多水题的题解忘了传……

直接Treap

#include<cstdio>
#include<cstdlib>
 
int n,mn,tag=0,root,leave=0,cnt;
char s[2];
 
struct Treap{
    int l,r,v,rnd,siz,w;
}tree[100005];
 
void Pre(){
tree[0].l=0;
tree[0].r=0;
root=0;
cnt=0;
srand(123465);
}
 
void Pushup(int rt){
tree[rt].siz=tree[tree[rt].l].siz+tree[tree[rt].r].siz+tree[rt].w;
}
 
void Lr(int &p){
int q=tree[p].r;
tree[p].r=tree[q].l;
tree[q].l=p;
tree[q].siz=tree[p].siz;
Pushup(p);
p=q;
}
 
void Rr(int &p){
int q=tree[p].l;
tree[p].l=tree[q].r;
tree[q].r=p;
tree[q].siz=tree[p].siz;
Pushup(p);
p=q;
}
 
void Ins(int &rt,int x){
if(!rt){
    rt=++cnt;
    tree[rt].l=0;
    tree[rt].r=0;
    tree[rt].v=x;
    tree[rt].siz=1;
    tree[rt].w=1;
    tree[rt].rnd=rand()<<15+rand();
    return;
}
tree[rt].siz++;
if(tree[rt].v>x){
    Ins(tree[rt].l,x);
    if(tree[tree[rt].l].rnd<tree[rt].rnd)Rr(rt);
    return;
}
else {
    Ins(tree[rt].r,x);
    if(tree[tree[rt].r].rnd<tree[rt].rnd)Lr(rt);
}
}
 
int Del(int &rt){
if(rt==0)return 0;
if(tree[rt].v+tag<0){
    int temp=tree[tree[rt].l].siz+1;
    rt=tree[rt].r;
    return temp+Del(rt);
}
int temp=Del(tree[rt].l);
tree[rt].siz-=temp;
return temp;
}
 
int Find(int rt,int x){
if(rt==0)return 0;
if(x<=tree[tree[rt].l].siz)return Find(tree[rt].l,x);
else {
    if(x>tree[tree[rt].l].siz+1)return Find(tree[rt].r,x-tree[tree[rt].l].siz-1);
    return tree[rt].v+tag;
}
}
 
int main(){
freopen("1503.in","r",stdin);
freopen("1503.out","w",stdout);
scanf("%d %d",&n,&mn);
for(int i=1;i<=n;i++){
    int Ts;
    scanf("%s %d",s,&Ts);
    if(s[0]=='I'){if(Ts>=mn){Ins(root,Ts-tag-mn);}}
    if(s[0]=='A'){tag+=Ts;}
    if(s[0]=='S'){tag-=Ts;leave+=Del(root);}
    if(s[0]=='F'){if(Ts>tree[root].siz)puts("-1");else printf("%d\n",Find(root,tree[root].siz-Ts+1)+mn);}
}
printf("%d\n",leave);
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
7
2016
0

[BZOJ4196] [Noi2015]软件包管理器

树链剖分直接上

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
 
int dep[100005],top[100005],id[100005],pre[100005],n,q,en,h[100005],fa[100005],son[100005],siz[100005],sn;
 
struct Edge{
int b,next;
}e[100005];
 
void AddEdge(int sa,int sb){
if(sa==sb)return;
e[++en].b=sb;
e[en].next=h[sa];
h[sa]=en;
}
 
struct SegTree{
int tag,sum,l,r,rem;
}tree[400005];
 
void Pushdown(int rt){
if(tree[rt].rem){
    tree[rt*2].tag=0;
    tree[rt*2+1].tag=0;
    tree[rt*2].sum=0;
    tree[rt*2+1].sum=0;
    tree[rt].tag=0;
    tree[rt*2].rem=1;
    tree[rt*2+1].rem=1;
    tree[rt].rem=0;
}
if(tree[rt].tag){
    tree[rt*2].tag=1;
    tree[rt*2+1].tag=1;
    tree[rt*2].rem=0;
    tree[rt*2+1].rem=0;
    tree[rt*2].sum=tree[rt*2].r-tree[rt*2].l+1;
    tree[rt*2+1].sum=tree[rt*2+1].r-tree[rt*2+1].l+1;
    tree[rt].tag=0;
}
}
 
void Pushup(int rt){
tree[rt].sum=tree[rt*2].sum+tree[rt*2+1].sum;
}
 
void Build(int rt,int l,int r){
tree[rt].l=l;
tree[rt].r=r;
if(l==r){
    tree[rt].rem=tree[rt].tag=tree[rt].sum=0;
    return;
}
int mid=l+r>>1;
Build(rt*2,l,mid);
Build(rt*2+1,mid+1,r);
tree[rt].rem=tree[rt].tag=tree[rt].sum=0;
}
 
void Add(int rt,int l,int r){
if(tree[rt].l>=l && tree[rt].r<=r){
    tree[rt].tag=1;
    tree[rt].rem=0;
    tree[rt].sum=tree[rt].r-tree[rt].l+1;
    return;
}
Pushdown(rt);
int mid=tree[rt].l+tree[rt].r>>1;
if(l<=mid)Add(rt*2,l,r);
if(r>mid)Add(rt*2+1,l,r);
Pushup(rt);
}
 
void Del(int rt,int l,int r){
if(tree[rt].l>=l && tree[rt].r<=r){
    tree[rt].rem=1;
    tree[rt].tag=0;
    tree[rt].sum=0;
    return;
}
Pushdown(rt);
int mid=tree[rt].l+tree[rt].r>>1;
if(l<=mid)Del(rt*2,l,r);
if(r>mid)Del(rt*2+1,l,r);
Pushup(rt);
}
 
int Sum(int rt,int l,int r){
if(tree[rt].l>=l && tree[rt].r<=r){
    return tree[rt].sum;
}
Pushdown(rt);
int mid=tree[rt].l+tree[rt].r>>1,ans=0;
if(l<=mid)ans+=Sum(rt*2,l,r);
if(r>mid)ans+=Sum(rt*2+1,l,r);
Pushup(rt);
return ans;
}
 
void dfs1(int u,int fat){
fa[u]=fat;
son[u]=0;
dep[u]=dep[fat]+1;
siz[u]=1;
for(int i=h[u];i;i=e[i].next){
    int v=e[i].b;
    dfs1(v,u);
    siz[u]+=siz[v];
    if(siz[son[u]]<siz[v])son[u]=v;
}
}
 
void dfs2(int u,int ux){
top[u]=ux;
id[u]=++sn;
pre[sn]=u;
if(son[u])dfs2(son[u],ux);
else return;
for(int i=h[u];i;i=e[i].next){
    int v=e[i].b;
    if(v==son[u] || v==fa[u])continue;
    dfs2(v,v);
}
}
 
int AddLine(int u){
int ans=0,f=top[u];
while(f!=1){
    ans+=id[u]-id[f]+1-Sum(1,id[f],id[u]);
    Add(1,id[f],id[u]);
    u=fa[f];
    f=top[u];
}
ans+=id[u]-id[1]+1-Sum(1,id[1],id[u]);
Add(1,id[1],id[u]);
return ans;
}
 
int DelSome(int u){
int ans=Sum(1,id[u],id[u]+siz[u]-1);
Del(1,id[u],id[u]+siz[u]-1);
return ans;
}
 
int main(){
freopen("4196.in","r",stdin);
freopen("4196.out","w",stdout);
scanf("%d",&n);
for(int i=2;i<=n;i++){
    int tp;
    scanf("%d",&tp);
    AddEdge(tp+1,i);
}
dfs1(1,0);
dfs2(1,1);
Build(1,1,n);
scanf("%d",&q);
for(int i=1;i<=q;i++){
    char s[10];
    int u;
    scanf("%s %d",s,&u);
    if(s[0]=='i')printf("%d\n",AddLine(u+1));
    else printf("%d\n",DelSome(u+1));
}
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
7
2016
0

[BZOJ4195] [Noi2015]程序自动分析

水并查集

#include<cstdio>
#include<algorithm>
using namespace std;

int t,n,f[1000005],g[1000005],index=0,ind;

struct Node{
int a,b,o;
}node[1000005];

int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);}
void Union(int x,int y){if(x>y)f[x]=y;else f[y]=x;}

int main(){
freopen("4195.in","r",stdin);
freopen("4195.out","w",stdout);
scanf("%d",&t);
while(t--){
scanf("%d",&n);
ind=0;
for(int i=1;i<=n;i++){
	scanf("%d %d %d",&node[i].a,&node[i].b,&node[i].o);
	g[++ind]=node[i].a;
	g[++ind]=node[i].b;
}
sort(g+1,g+ind+1);
ind=unique(g+1,g+ind+1)-g-1;
for(int i=1;i<=n;i++){
	node[i].a=lower_bound(g+1,g+ind+1,node[i].a)-g;
	node[i].b=lower_bound(g+1,g+ind+1,node[i].b)-g;
}
for(int i=1;i<=ind;i++)f[i]=i;
for(int i=1;i<=n;i++){
	if(node[i].o==1){Union(Find(node[i].a),Find(node[i].b));}
}
int flag=0;
for(int i=1;i<=n;i++){
	if(node[i].o==0 && Find(node[i].a)==Find(node[i].b)){puts("NO");flag=1;break;}
}
if(!flag)puts("YES");
}
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
7
2016
0

[BZOJ3928&4048] [Cerc2014] Outer space invaders

区间DP

离散化后考虑一段区间(l,r)(这里指的是出现时间的区间)

那么这段区间的R的最小值至少为这一段区间最高的线段(感觉讲的很抽象啊……最高的线段高度等于这个外星人离你的距离)

然后输出(0,tb)表示在[1,tb-1]能取到的最小代价,所以中间那个tb要++,因为我用的是开区间

#include<cstdio>
#include<algorithm>
using namespace std;

int n,table[10005],tb,f[1005][1005],T;

struct Plane{
int a,b,d;
}p[305];

int main(){
freopen("3928_4048.in","r",stdin);
freopen("3928_4048.out","w",stdout);
scanf("%d",&T);
while(T--){
    tb=0;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d %d %d",&p[i].a,&p[i].b,&p[i].d);
        table[++tb]=p[i].a;
        table[++tb]=p[i].b;
    }
    sort(table+1,table+tb+1);
    tb=unique(table+1,table+tb+1)-table-1;
    for(int i=1;i<=n;i++){
        p[i].a=lower_bound(table+1,table+tb+1,p[i].a)-table;
        p[i].b=lower_bound(table+1,table+tb+1,p[i].b)-table;
    }
    tb++;
    for(int len=0;len<=tb;len++){
        for(int i=0;i<=tb-len;i++){
            int j=i+len,H=-1;
            for(int k=1;k<=n;k++){
                if(i<p[k].a && p[k].b<j && (H==-1 || p[H].d<p[k].d))H=k;
            }
            if(H==-1)f[i][j]=0;
            else {
                f[i][j]=2100000000;
                for(int k=p[H].a;k<=p[H].b;k++){
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]+p[H].d);
                }
            }
        }
    }
    printf("%d\n",f[0][tb]);
}
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
5
2016
0

[BZOJ1857] [Scoi2010]传送带

三分点在AB和CD上面的位置

然后搞一搞就行了

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

struct Point{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
friend Point operator+(Point a,Point b){return Point(a.x+b.x,a.y+b.y);}
friend Point operator-(Point a,Point b){return Point(a.x-b.x,a.y-b.y);}
friend Point operator*(Point a,double k){return Point(a.x*k,a.y*k);}
double mold(){return sqrt(x*x+y*y);}
}A,B,C,D;

double V0,Vab,Vcd;
const double eps=1e-6;

double Calc(Point X,Point Y){
return (Y-X).mold()/V0+(Y-D).mold()/Vcd;
}

double sanfen2(Point x){
double l=0,r=1,res=(x-A).mold()/Vab;
while(r-l>eps){
	double mid1=l+(r-l)/3.0,mid2=r-(r-l)/3.0;
	double p1=Calc(x,C+(D-C)*mid1),p2=Calc(x,C+(D-C)*mid2);
	if(p1<p2)r=mid2;
	else l=mid1;
}
return res+Calc(x,C+(D-C)*l);
}

double sanfen1(){
double l=0,r=1;
while(r-l>eps){
	double mid1=l+(r-l)/3.0,mid2=r-(r-l)/3.0;
	double p1=sanfen2(A+(B-A)*mid1),p2=sanfen2(A+(B-A)*mid2);
	if(p1<p2)r=mid2;
	else l=mid1;
}
return sanfen2(A+(B-A)*l);
}

int main(){
freopen("1857.in","r",stdin);
freopen("1857.out","w",stdout);
scanf("%lf %lf %lf %lf %lf %lf %lf %lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y,&D.x,&D.y);
scanf("%lf %lf %lf",&Vab,&Vcd,&V0);
printf("%.2lf\n",sanfen1());
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
5
2016
0

[BZOJ1076] [SCOI2008]奖励关

状态压缩DP

根据期望的线性性,我们知道可以分开考虑每个物品在每一时刻出现的期望

然后把这些期望加起来再除以物品种类数(因为要求平均期望,而每种物品出现的概率都是1/k)

那么DP方程就是

f[i][j]+=max(f[i+1][j],f[i+1][j|bit[k]]+score[k]);(其中满足可以取k物品的条件)

f[i][j]+=f[i+1][j];(当前枚举到的k物品没办法取到所得到的上一次的平均得分期望)

最后f[i][j]/=k就可以了

为什么要从f[i+1][j]推导f[i][j]?因为如果顺推的话有可能会枚举到无效的状态,而且最后没办法输出f[n][j]

所以只需要倒推就可以解决问题啦

#include<cstdio>
#include<algorithm>
using namespace std;

int k,n,bit[25],ist[25],score[25];
double f[105][1<<15];

int main(){
freopen("1076.in","r",stdin);
freopen("1076.out","w",stdout);
scanf("%d %d",&n,&k);
for(int i=1;i<=20;i++)bit[i]=1<<(i-1);
for(int i=1;i<=k;i++){
	scanf("%d",&score[i]);
	int tp;
	for(int j=0;scanf("%d",&tp),tp;j++){
		ist[i]|=bit[tp];
	}
}
for(int i=n;i>=1;i--){
	for(int j=0;j<=bit[k+1]-1;j++){
		for(int l=1;l<=k;l++){
			if((j&ist[l])==ist[l]){
				f[i][j]+=max(f[i+1][j],f[i+1][j|bit[l]]+score[l]);
			}
			else f[i][j]+=f[i+1][j];
		}
		f[i][j]/=k;
	}
}
printf("%.6f\n",f[1][0]);
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
3
2016
0

[BZOJ1664] [Usaco2006 Open]County Fair Events 参加节日庆祝

排序直接做就行了

#include<cstdio>
#include<algorithm>
using namespace std;

int n,ans=0;

struct Event{
int s,t;
friend bool operator<(Event a,Event b){
return (a.t<b.t)||(a.t==b.t && a.s<b.s);
}
}e[10005];

int main(){
freopen("1664.in","r",stdin);
freopen("1664.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++){
	scanf("%d %d",&e[i].s,&e[i].t);
	e[i].t+=e[i].s;
}
sort(e+1,e+n+1);
int last=0;
for(int i=1;i<=n;i++){
	if(e[i].s>=e[last].t){
		ans++;
		last=i;
	}
	else if(e[i].t<e[last].t){
		last=i;
	}
}
printf("%d\n",ans);
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
3
2016
0

[BZOJ1683] [Usaco2005 Nov]City skyline 城市地平线

水题

以后交题目一定要检查调试有没有删掉

因为这个WA了一次……

简单的单调栈

#include<cstdio>
#include<stack>
using namespace std;

stack<int> S;

int n,w,ans,f[500005]={0};

int main(){
freopen("1683.in","r",stdin);
freopen("1683.out","w",stdout);
scanf("%d %d",&n,&w);
for(int i=1;i<=n;i++){
	int tpa,tpb;
	scanf("%d %d",&tpa,&tpb);
	int last=-1;
	while(!S.empty() && S.top()>tpb){int res=S.top();S.pop();if(res!=last){ans++;last=res;}}
	S.push(tpb);
}
while(!S.empty()){
	if(f[S.top()]==0 && S.top()){
		f[S.top()]++;
		ans++;
	}
	S.pop();
}
printf("%d\n",ans);
return 0;
}
Category: BZOJ | Tags: OI bzoj
3
3
2016
0

[BZOJ2594] [Wc2006]水管局长数据加强版

事实证明Lvat_s就是一个sb。。。

这题调试了2天

其实死在了一个很明显的错误上面

在倒数第二个关于q的循环里,我写道:

if(reans>e[i].v){……}

此时i明明表示q好不好……

正确的写法是:

if(reans>e[ask[i].ans].v){……}

还是贴一下代码吧,跑得很慢(19104ms)

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int n,m,q,f[100005];

void Read(int &x){
char ch;
while((ch=getchar())<'0' || ch>'9');
x=ch-'0';
while((ch=getchar())>='0' && ch<='9')x=x*10+ch-'0';
}

struct Node{
int v,mx,rev,id;
Node *ch[2],*fa,*mxe;
Node(int val,Node *fat);
void Pushdown();
void Pushup();
}*root[1100005],*Null;

Node::Node(int val,Node *fat){
ch[0]=ch[1]=Null;
if(val)mxe=this;
else mxe=Null;
fa=fat;
v=mx=val;
rev=id=0;
}

void Node::Pushdown(){
if(rev){
	if(ch[0]!=Null)ch[0]->rev^=1;
	if(ch[1]!=Null)ch[1]->rev^=1;
    swap(ch[0]->ch[0],ch[0]->ch[1]);
    swap(ch[1]->ch[0],ch[1]->ch[1]);
    rev=0;
}
}

void Node::Pushup(){
mx=v;
if(v)mxe=this;
else mxe=Null;
if(ch[0]!=Null && ch[0]->mx>mx){mx=ch[0]->mx;mxe=ch[0]->mxe;}
if(ch[1]!=Null && ch[1]->mx>mx){mx=ch[1]->mx;mxe=ch[1]->mxe;}
}

int Notroot(Node *p){
return (p->fa->ch[0]==p)||(p->fa->ch[1]==p);
}

void Prepare(Node *p){
if(Notroot(p))Prepare(p->fa);
p->Pushdown();
}

void Rotate(Node *x,int kind){
Node *y=x->fa,*z=y->fa;
y->ch[!kind]=x->ch[kind];
if(x->ch[kind]!=Null)x->ch[kind]->fa=y;
x->fa=z;
if(Notroot(y))z->ch[z->ch[1]==y]=x;
y->fa=x;
x->ch[kind]=y;
y->Pushup();
x->Pushup();
}

void Splay(Node *x){
Prepare(x);
while(Notroot(x)){
	Node *y=x->fa,*z=y->fa;
	if(!Notroot(y))Rotate(x,y->ch[0]==x);
	else {
		if(y->ch[0]==x && z->ch[0]==y){Rotate(y,1);Rotate(x,1);}
		else if(y->ch[1]==x && z->ch[0]==y){Rotate(x,0);Rotate(x,1);}
		else if(y->ch[0]==x && z->ch[1]==y){Rotate(x,1);Rotate(x,0);}
		else {Rotate(y,0);Rotate(x,0);}
	}
}
}

void Access(Node *x){
for(Node *y=Null;x!=Null;y=x,x=x->fa){Splay(x);x->ch[1]=y;x->Pushup();}
}

void Makeroot(Node *x){
Access(x);
Splay(x);
x->rev^=1;
swap(x->ch[0],x->ch[1]);
}

void Link(Node *x,Node *y){
Makeroot(x);
x->fa=y;
}

void Cut(Node *x,Node *y){
Makeroot(x);
Access(y);
Splay(y);
if(y->ch[0]==x){y->ch[0]=Null;x->fa=Null;}
}

int GetMx(Node *x,Node *y){
Makeroot(x);
Access(y);
Splay(y);
return y->mx;
}

Node *MxAddress(Node *x,Node *y){
Makeroot(x);
Access(y);
Splay(y);
return y->mxe;
}

Node *GetNull(){
Node *p=new Node(0,Null);
p->fa=p->ch[0]=p->ch[1]=p->mxe=p;
p->v=p->mx=-2100000000;
p->rev=p->id=0;
return p;
}

Node *ToLct(int x){
return root[x];
}

struct Edge{
int a,b,v,id,del;
friend bool operator<(Edge a,Edge b){
return (a.a<b.a)||(a.a==b.a && a.b<b.b);
}
}e[1000005];

bool cmp1(Edge a,Edge b){
return a.v<b.v;
}

bool cmp2(Edge a,Edge b){
return a.id<b.id;
}

struct Ask{
int k,x,y,ans;
}ask[100005];

int Div(int x,int y){
int l=1,r=m;
while(l<=r){
	int mid=(l+r)>>1;
	if(e[mid].a==x && e[mid].b==y)return mid;
	if(e[mid].a<x || (e[mid].a==x && e[mid].b<y)){l=mid+1;}
	else r=mid-1;
}
return (l+r)>>1;
}

int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);}
void Union(int x,int y){if(x<y)f[y]=x;else f[x]=y;}

int main(){
freopen("2594.in","r",stdin);
freopen("2594.out","w",stdout);
Read(n);Read(m);Read(q);
Null=GetNull();
for(int i=1;i<=m;i++){
	Read(e[i].a);Read(e[i].b);Read(e[i].v);
	if(e[i].a>e[i].b)swap(e[i].a,e[i].b);
}
sort(e+1,e+m+1,cmp1);
for(int i=1;i<=n;i++)root[i]=new Node(0,Null);
for(int i=1;i<=m;i++){
	e[i].id=i;
	root[i+n]=new Node(e[i].v,Null);
}
sort(e+1,e+m+1);
for(int i=1;i<=q;i++){
	Read(ask[i].k);
	Read(ask[i].x);
	Read(ask[i].y);
	if(ask[i].x>ask[i].y)swap(ask[i].x,ask[i].y);
	if(ask[i].k==2){
		int sci=Div(ask[i].x,ask[i].y);
		ask[i].ans=e[sci].id;
		e[sci].del=1;
	}
}
sort(e+1,e+m+1,cmp2);
for(int i=1;i<=n;i++)f[i]=i;
int tot=0;
for(int i=1;i<=m;i++){
	root[i+n]->id=i;
	if(!e[i].del && Find(e[i].a)!=Find(e[i].b)){
		Union(Find(e[i].a),Find(e[i].b));
		Link(ToLct(e[i].a),ToLct(i+n));
		Link(ToLct(e[i].b),ToLct(i+n));
		tot++;
		if(tot==n-1)break;
	}
}
for(int i=q;i>=1;i--){
	if(ask[i].k==1){
		ask[i].ans=GetMx(ToLct(ask[i].x),ToLct(ask[i].y));
	}
	else {
		Node *mx=MxAddress(ToLct(ask[i].x),ToLct(ask[i].y));
		int reans=mx->mx;
		if(reans>e[ask[i].ans].v){
			Cut(ToLct(e[mx->id].a),mx);
			Cut(ToLct(e[mx->id].b),mx);
			Link(ToLct(ask[i].x),ToLct(ask[i].ans+n));
			Link(ToLct(ask[i].y),ToLct(ask[i].ans+n));
		}
	}
}
for(int i=1;i<=q;i++){
	if(ask[i].k==1)printf("%d\n",ask[i].ans);
}
return 0;
}
Category: BZOJ | Tags: OI bzoj
2
29
2016
1

[BZOJ4320] ShangHai2006 Homework

最近感觉状态差极了

这种题要调40min……

UR水题不会做

以我3个月前的水平反而会了

感觉极其不爽,为什么有些人没有你努力竞赛照样比你搞得好那是因为这些人太假了,刷题都用小号给你造成不怎么刷题的假象(2016.3.10才发现……)

我觉得这和智商没什么关系

不说了,这是一个裸并查集

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,f[300005],is[300005],stx[555];

struct Read{
int opt,v,ans;
}read[100005];

int Find(int x){return x==f[x]?x:f[x]=Find(f[x]);}
void Union(int sa,int sb){if(sa<sb)f[sa]=sb;else f[sb]=sa;}

int main(){
freopen("4320.in","r",stdin);
freopen("4320.out","w",stdout);
scanf("%d",&n);
memset(stx,127,sizeof(stx));
for(int i=1;i<=n;i++){
	char s[10];
	int val;
	scanf("%s %d",s,&val);
	read[i].opt=s[0]-'A';
	read[i].v=val;
	if(read[i].opt==0){
		for(int j=1;j<=550;j++)stx[j]=min(stx[j],val%j);
		is[val]=1;
	}
	else if(val<=550){
		read[i].ans=stx[val];
	}
}
f[300001]=300001;
for(int i=300000;i>=1;i--){if(!is[i])f[i]=Find(f[i+1]);else f[i]=i;}
for(int i=n;i>=1;i--){
	if(read[i].opt==0){
		Union(Find(read[i].v),Find(read[i].v+1));
	}
	else if(read[i].v>550){
		read[i].ans=2100000000;
		for(int j=0;j*read[i].v<=300000;j++){
			read[i].ans=min(read[i].ans,(Find(read[i].v*j==0?1:read[i].v*j)==300001?read[i].v-1:Find(read[i].v*j==0?1:read[i].v*j))%read[i].v);
		}
	}
}
for(int i=1;i<=n;i++){
	if(read[i].opt)printf("%d\n",read[i].ans);
}
return 0;
}
Category: BZOJ | Tags: 随笔 OI bzoj

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com