jxr你过来我保证不打死你!!!
故事是这样的……今天中午发现jxr早上发了一道题过来……
嗯,就是这题了。
一看到这题,我就想起了wty大爷的箴言。
论JB(划掉)偏题的危害。
这题简直就是数据结构10合1啊!!!
题目很良心(丧病),给了测试点的编号作为输入。
于是我们可以借鉴TKD的写法,写10个程序。。。。。(其实不到吧)
首先看第一个点,暴力没跑了。
第二个,只有查询?输出q个0就好了
第三个,啊咧终于到线段树了?n........卧槽这么大怎么做?离散化?好像可以搞。
首先考虑一个询问q,肯定是一个区间求和(单点也算区间),于是对于前面的操作只关心对这个区间的和有影响的,那么我们知道修改操作会覆盖掉增减操作,而增减操作是可加的,我们从这一询问的前一操作开始向1进行计算,如果是加减操作,我们统计操作区间内已经被修改过得点的个数,用去区间长度减去个数然后乘以值,就得到了变化量,当然对于修改操作可以同样这么干,因为修改的区间长度为1,要么可以改,要么不能改(被改过),对于修改操作在统计完后要把这个区间的被修改点个数+1,要注意下不要重复统计一个点。
然而,我线段树写挂了TAT,所以用了个大暴力,1300多MS,不过好在题目时限2S
第四个,只有修改和查询,n很大,直接上map/hash
第五、六、七个,修改完之后的数组相当于初始数组,然后有区间加减、区间求和,查询点值相当于区间求和。这个n嘛,有点略大,其实朴素线段树也是可以过的(吧),参见bzoj 普通的vEB树,100W的数据朴素可以险过。当然如果会zkw最好(我是沙茶我不会),然而呢,我用了一种很坑爹的方法,树状数组,显然这些操作啊查询啊都是满足区间减法的,树状数组妥妥的,不过好像比zkw线段树长一点。
第八、九个,啊哈终于到线段树了,很普通的线段树,这两个点可以写成一颗线段树(不用担心溢出)
第十个点,第四个点的增强版,其实我想写trie的,但是目测要炸空间,于是用map水了一下,顺便复习了下string的用法(好难用WA了好几次),然后就过了。
再也不写码农题了TAT
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<string> #define lc o<<1 #define rc o<<1|1 using namespace std; typedef long long ll; void noneed(){ puts("-1"); } namespace solve1{ ll a[1100]; int main(){ int l,r,n,q,opt;ll x; scanf("%d%d",&q,&n); while(q--){ scanf("%d",&opt); if(opt==1){ scanf("%d%lld",&l,&x); noneed(); a[l]=x; }else if(opt==2){ scanf("%d",&l); printf("%lld\n",a[l]); }else if(opt==3){ noneed(); scanf("%d%d%lld",&l,&r,&x); for(int i=l;i<=r;i++) a[i]+=x; }else{ scanf("%d%d",&l,&r); x=0; for(int i=l;i<=r;i++) x+=a[i]; printf("%lld\n",x); } } return 0; } } namespace solve2{ int main(){ int q;scanf("%d",&q); while(q--)puts("0"); return 0; } } namespace solve3{ struct opt{ int op; ll l,r,x; }a[1100]; ll modify_point[1100]; int top; ll solve(int pos){ ll ans=0,l=a[pos].l,r=a[pos].r; top=0; for(int i=pos-1;i>=1;i--){ ll ql=max(l,a[i].l),qr=min(r,a[i].r); if(ql>qr)continue; ll cnt=0; for(int j=1;j<=top;j++) if(ql<=modify_point[j]&&modify_point[j]<=qr) cnt++; ans+=(qr-ql+1-cnt)*a[i].x; if(a[i].op==1)modify_point[++top]=a[i].l; } return ans; } int main(){ int q; ll n; scanf("%d%lld",&q,&n); for(int i=1;i<=q;i++){ scanf("%d",&a[i].op); if(a[i].op==1){ scanf("%lld%lld",&a[i].l,&a[i].x); a[i].r=a[i].l; }else if(a[i].op==2){ scanf("%lld",&a[i].l); a[i].r=a[i].l; }else if(a[i].op==3){ scanf("%lld%lld%lld",&a[i].l,&a[i].r,&a[i].x); }else{ scanf("%lld%lld",&a[i].l,&a[i].r); } } for(int i=1;i<=q;i++) if(a[i].op==2||a[i].op==4) printf("%lld\n",solve(i)); else noneed(); return 0; } } namespace solve4{ map<ll,ll>mp; int main(){ ll q,n;scanf("%lld%lld",&q,&n); while(q--){ int op;ll x,y; scanf("%d",&op); if(op==1){ scanf("%lld%lld",&x,&y); mp[x]=y; noneed(); }else{ scanf("%lld",&x); if(mp.count(x))printf("%lld\n",mp[x]); else puts("0"); } } return 0; } } namespace solve5{ #define lb(x) (x&-x) const int N=1048575+5; int n; ll d[N],s[N]; void add(int x,ll v){ for(;x<=n;x+=lb(x))d[x]+=v; } void update(int l,int r,ll v){ add(l,v);add(r+1,-v); } ll query(int x){ ll ans=s[x]; for(;x>0;x-=lb(x))ans+=d[x]; return ans; } int main(){ int q,op,l,r;ll x; scanf("%d%d",&q,&n); while(q--){ scanf("%d",&op); if(op==1){ scanf("%d%lld",&l,&x); s[l]=x; noneed(); }else if(op==2){ scanf("%d",&l); printf("%lld\n",query(l)); }else{ scanf("%d%d%lld",&l,&r,&x); update(l,r,x); noneed(); } } return 0; } } namespace solve67{ #define lb(x) (x&-x) const int N=1048575+5; int n; ll d[N],di[N],s[N]; ll sumd(int x){ ll ans=0; for(;x>0;x-=lb(x))ans+=d[x]; return ans; } ll sumdi(int x){ ll ans=0; for(;x>0;x-=lb(x))ans+=di[x]; return ans; } ll sum(int x){ return s[x]-sumdi(x)+(x+1)*sumd(x); } ll add(ll x,ll v,ll vi){ for(;x<=n;x+=lb(x)) d[x]+=v,di[x]+=vi; } void update(int l,int r,ll v){ add(l,v,l*v); add(r+1,-v,-(r+1)*v); } ll query(int l,int r){ return sum(r)-sum(l-1); } int main(){ int q,op,l,r;ll x; bool flag=true; scanf("%d%d",&q,&n); while(q--){ scanf("%d",&op); if(op!=1&&flag){ for(int i=1;i<=n;i++) s[i]+=s[i-1]; flag^=1; } if(op==1){ scanf("%d%lld",&l,&x); s[l]=x; noneed(); }else if(op==2){ scanf("%d",&l); printf("%lld\n",query(l,l)); }else if(op==3){ scanf("%d%d%lld",&l,&r,&x); update(l,r,x); noneed(); }else{ scanf("%d%d",&l,&r); printf("%lld\n",query(l,r)); } } return 0; } } namespace solve89{ const int N=131071+5; struct Node{ int l,r; ll sum,add; }tr[N<<2]; void pushup(int o){ tr[o].sum=tr[lc].sum+tr[rc].sum; } void pushdown(int o){ if(tr[o].add){ tr[lc].add+=tr[o].add;tr[rc].add+=tr[o].add; int len=tr[o].r-tr[o].l+1; tr[lc].sum+=(len-(len>>1))*tr[o].add; tr[rc].sum+=(len>>1)*tr[o].add; tr[o].add=0; } } void build(int o,int l,int r){ tr[o].l=l;tr[o].r=r; tr[o].sum=tr[o].add=0; if(l==r)return; int mid=l+r>>1; build(lc,l,mid);build(rc,mid+1,r); } void modify(int o,int p,ll v){ int l=tr[o].l,r=tr[o].r; if(l==r)tr[o].sum=v; else{ pushdown(o); int mid=l+r>>1; if(p<=mid)modify(lc,p,v); else modify(rc,p,v); pushup(o); } } void add(int o,int a,int b,ll v){ int l=tr[o].l,r=tr[o].r; if(l==a&&b==r)tr[o].sum+=(r-l+1)*v,tr[o].add+=v; else{ pushdown(o); int mid=l+r>>1; if(b<=mid)add(lc,a,b,v); else if(mid<a)add(rc,a,b,v); else add(lc,a,mid,v),add(rc,mid+1,b,v); pushup(o); } } ll query(int o,int a,int b){ int l=tr[o].l,r=tr[o].r; if(l==a&&b==r)return tr[o].sum; else{ pushdown(o); int mid=l+r>>1; if(b<=mid)return query(lc,a,b); else if(mid<a)return query(rc,a,b); else return query(lc,a,mid)+query(rc,mid+1,b); } } int main(){ int n,q,op,l,r;ll x; scanf("%d%d",&q,&n); build(1,1,n); while(q--){ scanf("%d",&op); if(op==1){ scanf("%d%lld",&l,&x); modify(1,l,x); noneed(); }else if(op==2){ scanf("%d",&l); printf("%lld\n",query(1,l,l)); }else if(op==3){ scanf("%d%d%lld",&l,&r,&x); add(1,l,r,x); noneed(); }else{ scanf("%d%d",&l,&r); printf("%lld\n",query(1,l,r)); } } return 0; } } namespace solve10{ map<string,string>mp; int main(){ int q,op; char x[100],y[100]; scanf("%d%s",&q,x); while(q--){ scanf("%d",&op); if(op==1){ scanf("%s%s",x,y); string t1(x),t2(y); mp[t1]=t2; noneed(); }else{ scanf("%s",x); string t(x); if(mp.count(t)) cout<<mp[t]<<endl; else puts("0"); } } return 0; } } int main(){ int id;scanf("%d",&id); if(id<=5)return solve1::main(); if(id<=10)return solve2::main(); if(id<=15)return solve3::main(); if(id<=20)return solve4::main(); if(id<=25)return solve5::main(); if(id<=35)return solve67::main(); if(id<=45)return solve89::main(); if(id<=50)return solve10::main(); return 0; }