1、 入门题:hdu1166敌兵布阵
单点更新区间求和
线段树:
using namespace std; struct node { int l,r,sum; }num[maxn*4]; int m[maxn]; char s[10]; int t,n,a,b; void build(int root,int l,int r) { num[root].l=l; num[root].r=r; if(num[root].l==num[root].r) { num[root].sum=m[l];return; } int mid=(num[root].l+num[root].r)/2; build(root<<1,l,mid); build(root<<1|1,mid+1,r); num[root].sum=num[root<<1].sum+num[root<<1|1].sum; } void update(int root,int pos,int data) { if(num[root].l==num[root].r) { num[root].sum=data; return; } int mid=(num[root].l+num[root].r)/2; if(pos<=mid) update(root<<1,pos,data); else update(root<<1|1,pos,data); num[root].sum=num[root<<1].sum+num[root<<1|1].sum; } int query(int root,int L,int R) { if(L<=num[root].l&&R>=num[root].r) { return num[root].sum; } int mid=(num[root].l+num[root].r)/2; int ans=0; if(L<=mid) ans+=query(root<<1,L,R); if(R>mid) ans+=query(root<<1|1,L,R); return ans; } int main() { freopen("data.in.txt","r",stdin); while(~scanf("%d",&t)) { int cnt=1; while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&m[i]); build(1,1,maxn); printf("Case %d: \n",cnt++); while(~scanf("%s",s)) { if(strcmp(s,"END")==0) break; scanf("%d%d",&a,&b); if(strcmp(s,"Add")==0) { m[a]+=b; update(1,a,m[a]); } if(strcmp(s,"Sub")==0) { m[a]-=b; update(1,a,m[a]); } if(strcmp(s,"Query")==0) { if(a>b) swap(a,b); printf("%d\n",query(1,a,b)); } } } } return 0; }
int lowbit(int i) { return i&(-i); } void update(int i,int x) { while(i<=n) { tree[i]+=x; i+=lowbit(i); } } int query(int n) { int sum=0; while(n>0) { sum+=tree[n]; n-=lowbit(n); } return sum; } int main() { int t;scanf("%d",&t); for(int cas=1;cas<=T;cas++) { memset(tree,0,sizeof(tree)); scanf("%d",&n); for(int i=1;i<=n;i++) { int x;scanf("%d",&x); update(i,x); } char str[10]; while(~scanf("%s",str)&&strcmp(str,"END")) { inta,b;scanf("%d%d",&a,&b); if(str[0]=='Q') printf("%d\n",Query(b)-Query(a-1)); elseif(str[0]=='S')Update(a,-b); else Update(a,b); } } return 0; }
区间更新求总和 ,不写懒惰标记也能过==看我的这篇
#include <iostream> #include <cstdio> using namespace std; const int maxn=1e5+5; #define l_t 2*root #define r_t 2*root+1 struct node{ int l,r,val,tag; //tag:1 2 3 -1 int mid(){ return (l+r)/2; } }tree[maxn<<2]; void update(int a,int b,int root,int tg){ if(a==tree[root].l&&b==tree[root].r){ tree[root].tag=tg; tree[root].val=(tree[root].r-tree[root].l+1)*tg; return ; } if(tree[root].tag!=-1){ tree[l_t].tag=tree[root].tag; tree[l_t].val=tree[l_t].tag*(tree[l_t].r-tree[l_t].l+1); tree[r_t].tag=tree[root].tag; tree[r_t].val=tree[r_t].tag*(tree[r_t].r-tree[r_t].l+1); tree[root].tag=-1; } int m=tree[root].mid(); if(a>m) update(a,b,r_t,tg); else if(b<=m) update(a,b,l_t,tg); else { update(a,m,l_t,tg); update(m+1,b,r_t,tg); } tree[root].val=tree[l_t].val+tree[r_t].val; } void build(int l,int r,int root){ tree[root].l=l; tree[root].r=r; tree[root].tag=-1; if(r==l){ tree[root].val=1; return ; } int mid=(l+r)/2; build(l,mid,l_t); build(mid+1,r,r_t); tree[root].val=tree[l_t].val+tree[r_t].val; } int main() { //freopen("cin.txt","r",stdin); int ca; cin>>ca; for(int k=1;k<=ca;k++){ int n,q; scanf("%d",&n); build(1,n,1); scanf("%d",&q); for(int i=0;i<q;i++){ int x,y,z; scanf("%d%d%d",&x,&y,&z); update(x,y,1,z); } printf("Case %d: The total value of the hook is %d.\n",k,tree[1].val); } return 0; }
求依次把数组的第一个数放到最后,组成的新数组的逆序数的最小值。给定的数是0~n-1之间的。
整体的思路是先求出来把每个数插到最后相对比放在原始位置变动的多少,这个相对值+原始的逆序数值就是最终结果。关键是相对值如何求?由于每个数都是0~n-1之间,省了离散化这个步骤,我们知道n-1-a[i]是比这个数大的个数,也就是这个数后面有多少个比大的,(我们让每步的初始状态是读入的这个数是第一个)那么我们把这个刚刚读入的数放到最后,里外里就为逆序数贡献了n-1-2*a[i],中间的不用管,反正没为逆序数总值做贡献。 可以看我这篇:感觉写的还没有我这个详细呢
#include <iostream> #include<cstdio> using namespace std; struct node { int l,r,sum; }tree[150000]; void build(int root,int l,int r) { tree[root].l=l,tree[root].r=r; if(tree[root].l==tree[root].r) { tree[root].sum=0; return; } build(root<<1,l,(l+r)/2); build(root<<1|1,(l+r)/2+1,r); tree[root].sum=0; } void update(int root,int pos,int val) { if(tree[root].l==tree[root].r) { tree[root].sum=val; return; } int mid=(tree[root].l+tree[root].r)/2; if(pos<=mid) update(root<<1,pos,val); else update(root<<1|1,pos,val);///这里写成了build 你脑子在想什么== tree[root].sum=min(tree[root<<1].sum,tree[root<<1|1].sum); } int main() { //freopen("cin.txt","r",stdin); int n,a[12],ret;/// while(~scanf("%d",&n)) { build(1,1,n); ret=0; for(int i=0;i<n;i++) { scanf("%d",&a[i]); ret+=(n-1-2*a[i]); update(1,a[i],ret); } ret=0; for(int i=0;i<n-1;i++) { for(int j=i+1;j<n;j++) { if(a[i]>a[j]) ret++; } } printf("%d\n",ret+tree[1].sum); } return 0; }
现在看来也没什么好说的,注意题中要求的顺序
#include <iostream> #include<cstring> #include<cstdio> using namespace std; struct node { int l,r,lsum,rsum,sum,loop; }tree[400000]; int Find_Max(int a,int b ,int c) { int maxn=a>b?a:b; maxn=maxn>c?maxn:c; return maxn; } void push_down(int t) { if(tree[t].loop!=-1) { tree[t<<1].loop=tree[t<<1|1].loop=tree[t].loop; if(tree[t].loop) { tree[t<<1].lsum=tree[t<<1].rsum=tree[t<<1].sum=0; tree[t<<1|1].lsum=tree[t<<1|1].rsum=tree[t<<1|1].sum=0; } else //if(tree[t].loop==0) { tree[t<<1].lsum=tree[t<<1].rsum=tree[t<<1].sum=tree[t<<1].r-tree[t<<1].l+1; tree[t<<1|1].lsum=tree[t<<1|1].rsum=tree[t<<1|1].sum=tree[t<<1|1].r-tree[t<<1|1].l+1; } tree[t].loop=-1; } } void push_up(int l,int r,int t) { tree[t].lsum=tree[t<<1].lsum; tree[t].rsum=tree[t<<1|1].rsum; int x=(l+r)/2; if(tree[t].lsum==x-l+1) tree[t].lsum+=tree[t<<1|1].lsum; if(tree[t].rsum==r-x) tree[t].rsum+=tree[t<<1].rsum; tree[t].sum=Find_Max(tree[t<<1].sum,tree[t<<1|1].sum,tree[t<<1].rsum+tree[t<<1|1].lsum);/// } void build(int l,int r,int t) { tree[t].l=l,tree[t].r=r; tree[t].sum=tree[t].lsum=tree[t].rsum=r-l+1; tree[t].loop=-1; if(l==r) return; int x=(l+r)/2; build(l,x,2*t); build(x+1,r,2*t+1); } void update_tree(int l,int r,int t,int cnt) { if(tree[t].l==l&&tree[t].r==r) { tree[t].loop=cnt; if(cnt) tree[t].lsum=tree[t].rsum=tree[t].sum=0; else tree[t].lsum=tree[t].rsum=tree[t].sum=r-l+1; return; } push_down(t); int x=(tree[t].l+tree[t].r)/2; if(x>=r) update_tree(l,r,2*t,cnt); else if(x+1<=l) update_tree(l,r,2*t+1,cnt); else { update_tree(l,x,2*t,cnt); update_tree(x+1,r,t<<1|1,cnt); } push_up(tree[t].l,tree[t].r,t); } int Query(int l,int r,int t,int cnt) { if(l==r) return 1; int x=(l+r)/2; push_down(t); if(tree[t<<1].sum>=cnt) return Query(l,x,t<<1,cnt); else if(tree[t<<1].rsum+tree[t<<1|1].lsum>=cnt)return x-tree[t<<1].rsum+1; else return Query(x+1,r,t<<1|1,cnt); } int main() { // freopen("cin.txt","r",stdin); int i,j,n,m,x,y; while(~scanf("%d%d",&n,&m)) { build(1,n,1); while(m--) { scanf("%d",&i); if(i==1) { scanf("%d",&x); if(tree[1].sum<x) { printf("0\n"); continue; } y=Query(1,n,1,x); printf("%d\n",y); update_tree(y,y+x-1,1,1); } else { scanf("%d%d",&x,&y); update_tree(x,x+y-1,1,0); } } } return 0; }
展板上贴窄公告,优先选择最上最左的,输出行号。和刚刚那个题一样,也需要注意优先级的问题,更要注意长度是有限制的,不像上面那个是一维的
#include <iostream> #include<cstdio> #include<cstring> #define maxn 200000 using namespace std; struct bill { int l,r,ans; }num[maxn*4]; int m; int w,h,n; void build(int L,int R,int root) { num[root].l=L; num[root].r=R; num[root].ans=w; if(L==R) return; build(L,(L+R)/2,root<<1); build((L+R)/2+1,R,root<<1|1); // } int update(int root,int m) { if(num[root].ans<m) return -1; if(num[root].l==num[root].r) { num[root].ans-=m; return num[root].l; } int ret; if(num[root<<1].ans>=m) ret=update(root<<1,m); else ret=update(root<<1|1,m); num[root].ans=max(num[root<<1].ans,num[root<<1|1].ans); return ret; } int main() { //freopen("data.in.txt","r",stdin); while(~scanf("%d%d%d",&h,&w,&n)) { build(1,min(n,h),1); for(int i=1;i<=n;i++) { scanf("%d",&m); printf("%d\n",update(1,m)); } } return 0; }===================================上面都是去年暑假做的水题,下面的是今年的练习,难度明显高了一个level======================================
简而言之就是交换次数==每个数前面比他大的总和 详细的代码见:
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 500005 int n; int c[maxn],b[maxn]; struct Node { int index,v; }node[maxn]; bool cmp(Node a,Node b) { return a.v<b.v; } int lowbit(int x) { return x&(-x); } void add(int i,int val) { while(i<=n) { c[i]+=val; i+=lowbit(i); } } int sum(int i) { int s=0; while(i>0) { s+=c[i]; i-=lowbit(i); } return s; } int main() { //freopen("cin.txt","r",stdin); while(~scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) { scanf("%d",&node[i].v); node[i].index=i; } memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); sort(node+1,node+1+n,cmp); b[node[1].index]=1; for(int i=2;i<=n;i++) { b[node[i].index]=i; } long long ans=0; for(int i=1;i<=n;i++) { add(b[i],1); ans+=(i-sum(b[i])); } printf("%I64d\n",ans); } return 0; }线段树做法
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 500005 struct node { int id,val; }num[maxn]; bool cmp(node n1,node n2) { return n1.val<n2.val; } struct Tree { int l,r,tot; }tree[maxn<<2]; int rank[maxn]; void build(int rt,int l,int r) { tree[rt].l=l;tree[rt].r=r; tree[rt].tot=0; if(l==r)return; int mid=(l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); } void update(int rt,int x) { tree[rt].tot++; if(tree[rt].l==tree[rt].r&&tree[rt].l==x) return; int mid=(tree[rt].l+tree[rt].r)/2; if(x<=mid)update(rt<<1,x); else update(rt<<1|1,x); } int query(int rt,int l,int r) { int sum=0; if(tree[rt].l==l&&tree[rt].r==r) return tree[rt].tot; int mid=(tree[rt].l+tree[rt].r)/2; if(r<=mid) sum=query(rt<<1,l,r); else if(l>mid) sum=query(rt<<1|1,l,r); else sum=query(rt<<1,l,mid)+query(rt<<1|1,mid+1,r); return sum; } int main() { // freopen("cin.txt","r",stdin); int n; while(~scanf("%d",&n)&&n) { for(int i=0;i<n;i++) { scanf("%d",&num[i].val); num[i].id=i; } sort(num,num+n,cmp); for(int i=0;i<n;i++) rank[num[i].id]=i+1; build(1,0,n+1); long long sum=0; for(int i=0;i<n;i++) { int x = rank[i]; sum+=query(1,x+1,n+1); update(1,x); } printf("%I64d\n",sum); } return 0; }
、树状数组区间更新单点求值hdu4267 点击我看博客
#include<cstdio> #include<cstring> using namespace std; int n,q,c[12][12][50010],tmp[50010]; int lowbit(int i) { return i&(-i); } void add(int t1,int t2,int i,int x) { while(i>0) { c[t1][t2][i]+=x; i-=lowbit(i); } } int query(int t1,int t2,int x) { int s=0; while(x<=n) { s+=c[t1][t2][x]; x+=lowbit(x); } return s; } int main() { //freopen("cin.txt","r",stdin); while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); int a,b,k,e,m; for(int i=1;i<=n;i++) { scanf("%d",&tmp[i]); } // for(int i=1;i<=n;i++) printf("%d ",c[i]); scanf("%d",&q); while(q--) { scanf("%d",&m); if(m==1) { scanf("%d%d%d%d",&a,&b,&k,&e); int num=(b-a)/k; int s=a%k; add(k,s,a-1,-e); add(k,s,b,e); } else { scanf("%d",&a); int sum=tmp[a]; for(int i=1;i<=10;i++) { sum+=query(i,a%i,a); } printf("%d\n",sum); } } } return 0; }
#include <iostream> #include<cstdio> #include<cstring> using namespace std; int tree[1050][1050],n,t,x,y,a,l,b,r,cmd; int lowbit(int i) { return i&(-i); } void update(int x,int y,int a) { for(int i=x;i<=n;) { for(int j=y;j<=n;) { tree[i][j]+=a; j+=lowbit(j); } i+=lowbit(i); } } int query(int x,int y) { int s=0; for(int i=x;i>0;i-=lowbit(i)) { for(int j=y;j>0;j-=lowbit(j)) s+=tree[i][j]; } return s; } int main() { // freopen("cin.txt","r",stdin); scanf("%d%d",&cmd,&n); memset(tree,0,sizeof(tree)); while(~scanf("%d",&cmd)) { if(cmd==3) break; if(cmd==1) { scanf("%d%d%d",&x,&y,&a); x++;y++; update(x,y,a); } else { scanf("%d%d%d%d",&l,&b,&r,&t); int sum=0; l++;b++;r++;t++; sum=query(r,t)+query(l-1,b-1)-query(l-1,t)-query(r,b-1); printf("%d\n",sum); } } return 0; }
#include <cstdio> #include <algorithm> #include<cstring> using namespace std; #define lson l , m , rt << 1 #define rson m + 1 , r , rt << 1 | 1 const int maxn = 11111; bool hash[maxn]; int li[maxn] , ri[maxn]; int X[maxn*3]; int col[maxn<<4]; int cnt; void push_down(int rt) { if(col[rt]!=-1) { col[rt<<1]=col[rt<<1|1]=col[rt]; col[rt]=-1; } } void update(int l,int r,int c,int L,int R,int rt) { if(l<=L&&R<=r) { col[rt]=c; return; } push_down(rt); int mid=(L+R)/2; if(l<=mid)update(l,r,c,L,mid,rt<<1); if(r>mid) update(l,r,c,mid+1,R,rt<<1|1);/// } void query(int l,int r,int rt) { if(col[rt]!=-1) { if(!hash[col[rt]]) cnt++; hash[col[rt]]=1; return; } if(l==r) return; int m=(l+r)/2; query(l,m,rt<<1); query(m+1,r,rt<<1|1); } int Bin(int num,int R) { int l=0,r=R-1,mid; while(l<=r) { mid=(l+r)/2; if(X[mid]==num) return mid; if(X[mid]<num) l=mid+1; else r=mid-1; } } int main() { // freopen("cin.txt","r",stdin); int t,n; scanf("%d",&t); while(t--) { int nn=0,m=1; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&li[i],&ri[i]),X[nn++]=li[i],X[nn++]=ri[i]; sort(X,X+nn); for(int i=1;i<nn;i++) if(X[i]!=X[i-1]) X[m++]=X[i]; for(int i=m-1;i>0;i--)if(X[i]!=X[i-1]+1)X[m++]=X[i-1]+1; sort(X,X+m); memset(col,-1,sizeof(col)); for(int i=0;i<n;i++) { int l=Bin(li[i],m); int r=Bin(ri[i],m); update(l,r,i,0,m,1); } cnt=0; memset(hash , false , sizeof(hash)); query(0,m,1); printf("%d\n",cnt); } return 0; }
#include <iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; struct node { int l,r; long long sum; }num[400005]; int n,m,t; void build(int l,int r,int i) { num[i].l=l; num[i].r=r; if(l==r) { scanf("%I64d",&num[i].sum); return; } int mid=(l+r)/2; build(l,mid,i<<1); build(mid+1,r,i<<1|1); num[i].sum=num[i<<1].sum+num[i<<1|1].sum; } void update(int l,int r,int rt) { if(num[rt].sum==(num[rt].r-num[rt].l+1)&&l==num[rt].l&&r==num[rt].r) return; if(num[rt].l==num[rt].r) { num[rt].sum=(int)sqrt(num[rt].sum*1.0); return; } int mid=(num[rt].l+num[rt].r)/2; if(r<=mid) update(l,r,rt<<1); else if(l>mid) update(l,r,rt<<1|1); else { update(l,mid,rt<<1); update(mid+1,r,rt<<1|1); } num[rt].sum=num[rt<<1].sum+num[rt<<1|1].sum; } long long query(int l,int r,int rt) { if(l==num[rt].l&&r==num[rt].r) return num[rt].sum; long long ans=0; int mid=(num[rt].l+num[rt].r)/2; if(r<=mid) ans+=query(l,r,rt<<1); else if(l>mid) ans+=query(l,r,rt<<1|1); else { ans+=query(l,mid,rt<<1); ans+=query(mid+1,r,rt<<1|1); } return ans; } int main() { // freopen("cin.txt","r",stdin); int cas=1; while(~scanf("%d",&n)) { printf("Case #%d:\n",cas++); build(1,n,1); scanf("%d",&m); while(m--) { int a,b; scanf("%d%d%d",&t,&a,&b); if(a>b) swap(a,b); if(t==0) update(a,b,1); else printf("%I64d\n",query(a,b,1)); } puts(""); } return 0; }
#include <iostream> #include<cstdio> #include<cstring> using namespace std; struct node { int l,r,tot; }num[800000]; int tmp; void build(int rt,int l,int r) { num[rt].l=l;num[rt].r=r; if(l==r) { num[rt].tot=0; return; } int mid=(l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); num[rt].tot=0; } void update(int rt,int pos,bool flag)///1:add 0:del { if(num[rt].l==num[rt].r) { if(flag) num[rt].tot++; else num[rt].tot--; return;///!!! } int mid=(num[rt].l+num[rt].r)/2; if(pos<=mid) update(rt<<1,pos,flag); else update(rt<<1|1,pos,flag); num[rt].tot=num[rt<<1].tot+num[rt<<1|1].tot; } int sum(int rt,int l,int r) { if(num[rt].r<l||num[rt].l>r) return 0; if(num[rt].r<=r&&num[rt].l>=l) return num[rt].tot; int mid=(num[rt].l+num[rt].r)/2; return sum(rt<<1,l,r)+sum(rt<<1|1,l,r); } void query(int rt,int ans) { if(ans>num[rt<<1].tot) { if(num[rt].l==num[rt].r) { tmp=num[rt].r; return; } query(rt<<1|1,ans-num[rt<<1].tot); } else query(rt<<1,ans); } int main() { // freopen("cin.txt","r",stdin); int q,a,b,m; while(~scanf("%d",&m)) { build(1,1,100000); while(m--) { scanf("%d",&q); if(q==0) { scanf("%d",&a); update(1,a,1); } else if(q==1) { scanf("%d",&a); if(sum(1,1,a)==sum(1,1,a-1)) printf("No Elment!\n"); else update(1,a,0); } else { scanf("%d%d",&a,&b); { int t=sum(1,1,a); tmp=0; query(1,t+b); if(tmp==100000)printf("Not Find!\n"); else printf("%d\n",tmp); } } } } return 0; }hdu4006The kth great number【线段树第k大】
#include <iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 1000000 struct node { int l,r,tot; }num[maxn*8]; void build(int rt,int l,int r) { num[rt].l=l;num[rt].r=r; if(l==r) { num[rt].tot=0; return; } int mid=(l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); num[rt].tot=0; } void update(int rt,int pos) { if(num[rt].l==num[rt].r) { if(num[rt].l==pos) num[rt].tot++; return; } int mid=(num[rt].l+num[rt].r)/2; if(pos<=mid) update(rt<<1,pos); else update(rt<<1|1,pos); num[rt].tot=num[rt<<1].tot+num[rt<<1|1].tot; } int query(int rt,int k) { if(k>num[rt<<1|1].tot) { if(num[rt].l==num[rt].r) { return num[rt].l; } query(rt<<1,k-num[rt<<1|1].tot); } else query(rt<<1|1,k); } int main() { // freopen("cin.txt","r",stdin); int n,k,a; char st[3]; while(~scanf("%d%d",&n,&k)) { build(1,1,maxn); while(n--) { scanf("%s",st); if(st[0]=='I') { scanf("%d",&a); update(1,a); } else printf("%d\n",query(1,k)); } } return 0; }
#include <iostream> #include<cstdio> #include<cstring> using namespace std; struct Node { int l,r,minn,maxn; }num[4000000]; int cnt[1000000]; int min(int a,int b){if(a<b)return a;return b;} int max(int a,int b){if(a>b)return a;return b;} void build(int rt,int l,int r) { num[rt].l=l;num[rt].r=r; if(l==r) { num[rt].maxn=cnt[l]; num[rt].minn=cnt[l]; return; } int mid=(l+r)/2; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); num[rt].maxn=max(num[rt<<1].maxn,num[rt<<1|1].maxn); num[rt].minn=min(num[rt<<1].minn,num[rt<<1|1].minn); } int query1(int rt,int l,int r) { if(num[rt].l==l&&num[rt].r==r) return num[rt].minn; int mid=(num[rt].l+num[rt].r)/2; if(r<=mid) return query1(rt<<1,l,r); else if(l>mid) return query1(rt<<1|1,l,r); else return min(query1(rt<<1,l,mid),query1(rt<<1|1,mid+1,r)); } int query2(int rt,int l,int r) { if(num[rt].l==l&&num[rt].r==r) return num[rt].maxn; int mid=(num[rt].l+num[rt].r)/2; if(r<=mid) return query2(rt<<1,l,r); else if(l>mid) return query2(rt<<1|1,l,r); else return max(query2(rt<<1,l,mid),query2(rt<<1|1,mid+1,r)); } int main() { // freopen("cin.txt","r",stdin); int n,k; while(~scanf("%d%d",&n,&k)) { for(int i=1;i<=n;i++)scanf("%d",&cnt[i]); build(1,1,n); for(int i=1;i<=n-k;i++) printf("%d ",query1(1,i,i+k-1)); printf("%d\n",query1(1,n-k+1,n)); for(int i=1;i<=n-k;i++) printf("%d ",query2(1,i,i+k-1)); printf("%d\n",query2(1,n-k+1,n)); } return 0; }
13、单点更新,区间求最值
#include <iostream> #include<cstdio> #include<cstring> using namespace std; #define maxn 500005 int a[37]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,7560,10080,15120,20160,25200,27720,45360,50400, 55440,83160,110880,166320,221760,277200,332640,498960,500001}; int b[37]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,64,72,80,84,90,96,100,108,120,128,144,160,168,180,192,200,1314521}; char name[maxn][15]; int pos[maxn]; struct node { int l,r,tot; }num[maxn*4]; void build(int rt,int l,int r) { int mid=(l+r)/2; num[rt].l=l;num[rt].r=r; if(l==r) { num[rt].tot=1; return; } // printf("rt=%d tot=%d\n",rt,num[rt].tot); build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); num[rt].tot=num[rt<<1].tot+num[rt<<1|1].tot; } int update(int rt,int k) { num[rt].tot--; if(num[rt].l==num[rt].r) return num[rt].l; if(k<=num[rt<<1].tot) update(rt<<1,k); else update(rt<<1|1,k-num[rt<<1].tot); } int main() { //freopen("cin.txt","r",stdin); int n,k; while(~scanf("%d%d",&n,&k)) { for(int i=1;i<=n;i++)scanf("%s%d",name[i],&pos[i]); // for(int i=1;i<=n;i++)printf("%s% d\n",name[i],pos[i]); build(1,1,n); int cnt=0; while(a[cnt]<=n) cnt++; cnt--; int ps=0; pos[ps]=0; // printf("tot=%d\n",num[1].tot); for(int i=0;i<a[cnt];i++) { if(pos[ps]>0) k = ((k + pos[ps] - 2) % num[1].tot + num[1].tot) % num[1].tot + 1; else k = ((k + pos[ps] - 1) % num[1].tot + num[1].tot) % num[1].tot + 1; // cout<<k<<endl; ps=update(1,k);//cout<<ps<<endl; } printf("%s %d\n",name[ps],b[cnt]); } return 0; }
#include <stdio.h> #include <string.h> #include <iostream> using namespace std; const int MAXN = 1010; struct Nodey { int l,r; int val; }; int n; int locx[MAXN],locy[MAXN]; struct Nodex { int l,r; Nodey sty[MAXN*3]; void build(int i,int _l,int _r) { sty[i].l = _l; sty[i].r = _r; sty[i].val = 0; if(_l == _r) { locy[_l] = i; return; } int mid = (_l + _r)>>1; build(i<<1,_l,mid); build((i<<1)|1,mid+1,_r); } void add(int i,int _l,int _r,int val) { if(sty[i].l == _l && sty[i].r == _r) { sty[i].val += val; return; } int mid = (sty[i].l + sty[i].r)>>1; if(_r <= mid)add(i<<1,_l,_r,val); else if(_l > mid)add((i<<1)|1,_l,_r,val); else { add(i<<1,_l,mid,val); add((i<<1)|1,mid+1,_r,val); } } }stx[MAXN*3]; void build(int i,int l,int r) { stx[i].l = l; stx[i].r = r; stx[i].build(1,1,n); if(l == r) { locx[l] = i; return; } int mid = (l+r)>>1; build(i<<1,l,mid); build((i<<1)|1,mid+1,r); } void add(int i,int x1,int x2,int y1,int y2,int val) { if(stx[i].l == x1 && stx[i].r == x2) { stx[i].add(1,y1,y2,val); return; } int mid = (stx[i].l + stx[i].r)/2; if(x2 <= mid)add(i<<1,x1,x2,y1,y2,val); else if(x1 > mid)add((i<<1)|1,x1,x2,y1,y2,val); else { add(i<<1,x1,mid,y1,y2,val); add((i<<1)|1,mid+1,x2,y1,y2,val); } } int sum(int x,int y) { int ret = 0; for(int i = locx[x];i;i >>= 1) for(int j = locy[y];j;j >>= 1) ret += stx[i].sty[j].val; return ret; } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int T; scanf("%d",&T); while(T--) { int q; scanf("%d%d",&n,&q); build(1,1,n); char op[10]; int x1,x2,y1,y2; while(q--) { scanf("%s",op); if(op[0] == 'C') { scanf("%d%d%d%d",&x1,&y1,&x2,&y2); add(1,x1,x2,y1,y2,1); } else { scanf("%d%d",&x1,&y1); if(sum(x1,y1)%2 == 0)printf("0\n"); else printf("1\n"); } } if(T)printf("\n"); } return 0; }15、
#include <cstdio> #include <algorithm> #include<cstring> using namespace std; #define maxn 200008 int n,tree[maxn],X[maxn],li[maxn],ri[maxn],nn,m,mm,ma; int lowbit(int i) { return i&(-i); } void update(int i,int x) { while(i<=ma) { tree[i]=tree[i]+x; i=i+lowbit(i); } } long long query(int n) { long long sum=0; while(n>0) { sum+=tree[n]; n=n-lowbit(n); } return sum; } int Bin(int num,int R) { int l=0,r=R-1,mid; while(l<=r) { mid=(l+r)/2; if(X[mid]==num) return mid; if(X[mid]<num) l=mid+1; else r=mid-1; } } int q[maxn]; int main() { // freopen("cin.txt","r",stdin); int t,cas=1; scanf("%d",&t); while(t--) { nn=0,m=1,mm; memset(X,0,sizeof(X)); scanf("%d%d",&n,&mm); for(int i=0;i<n;i++) scanf("%d%d",&li[i],&ri[i]),X[nn++]=li[i],X[nn++]=ri[i]; for(int i=0;i<mm;i++)scanf("%d",&q[i]),X[nn++]=q[i]; sort(X,X+nn); // for(int i=0;i<nn;i++)printf("x=%d ",X[i]);puts(""); for(int i=1;i<nn;i++) if(X[i]!=X[i-1]) X[m++]=X[i]; // for(int i=m-1;i>0;i--)if(X[i]-X[i-1]>=1)X[m++]=X[i-1]+1; sort(X,X+m); ma=m+1; // for(int i=0;i<m;i++)printf("x=%d ",X[i]);puts(""); // printf("m=%d\n",m); memset(tree,0,sizeof(tree)); for(int i=0;i<n;i++) { int l=Bin(li[i],m); int r=Bin(ri[i],m); // printf("l=%d r=%d\n",l+1,r+1); update(l+1,1); update(r+2,-1); // update(li[i],1);update(ri[i]+1,-1); } printf("Case #%d:\n",cas++); for(int i=0;i<mm;i++) { int qu=Bin(q[i],m); // printf("qu=%d\n",qu+1); printf("%I64d\n",query(qu+1)); } } return 0; }