维护区间和
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ls(p) (p<<1) 4 #define rs(p) (p<<1|1) 5 #define ll long long 6 const int MAXN=1e5+5; 7 struct node 8 { 9 ll sum,lazy; 10 node(){sum=0,lazy=0;} 11 }T[MAXN*4]; 12 int a[MAXN]; 13 int n,m; 14 inline void push_up(int p) 15 { 16 T[p].sum=T[ls(p)].sum+T[rs(p)].sum; 17 } 18 inline void build(int p,int l,int r) 19 { 20 if(l==r) 21 { 22 T[p].sum=a[l]; 23 return; 24 } 25 int mid=(l+r)>>1; 26 build(ls(p),l,mid); 27 build(rs(p),mid+1,r); 28 push_up(p); 29 } 30 inline void push_down(int p,int l,int r) 31 { 32 if(!T[p].lazy) return; 33 int mid=(l+r)>>1; 34 T[ls(p)].lazy+=T[p].lazy,T[rs(p)].lazy+=T[p].lazy; 35 T[ls(p)].sum+=T[p].lazy*(mid-l+1), 36 T[rs(p)].sum+=T[p].lazy*(r-mid); 37 T[p].lazy=0; 38 } 39 inline void update(int p,int l,int r,int nl,int nr,int k) 40 { 41 if(nl<=l&&nr>=r) 42 { 43 T[p].sum+=k*(r-l+1); 44 T[p].lazy+=k; 45 return; 46 } 47 push_down(p,l,r); 48 int mid=(l+r)>>1; 49 if(nl<=mid) update(ls(p),l,mid,nl,nr,k); 50 if(nr>=mid+1) update(rs(p),mid+1,r,nl,nr,k); 51 push_up(p); 52 } 53 ll query(int p,int l,int r,int nl,int nr) 54 { 55 ll ans=0; 56 if(nl<=l&&nr>=r) return T[p].sum; 57 push_down(p,l,r); 58 int mid=(l+r)>>1; 59 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr); 60 if(nr>=mid+1) ans+=query(rs(p),mid+1,r,nl,nr); 61 return ans; 62 } 63 int read() 64 { 65 int s=1,x=0;char ch=getchar(); 66 while(!isdigit(ch)){if(ch=='-') s=-1;ch=getchar();} 67 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 68 return s*x; 69 } 70 int main() 71 { 72 //freopen("testdata.in","r",stdin); 73 n=read();m=read(); 74 for(int i=1;i<=n;++i) a[i]=read(); 75 build(1,1,n); 76 int opt,x,y,k; 77 for(int i=1;i<=m;++i) 78 { 79 opt=read(); 80 if(opt==1)//update 81 { 82 x=read(),y=read(),k=read(); 83 update(1,1,n,x,y,k); 84 } 85 else //query 86 { 87 x=read(),y=read(); 88 cout<<query(1,1,n,x,y)<<endl; 89 } 90 } 91 return 0; 92 }
乘法优先,乘法分配律
维护区间和、区间乘积
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(n) (n<<1) 24 #define rs(n) (n<<1|1) 25 using namespace std; 26 const int MAXN=1e5+5; 27 int N,M,P; 28 int read() 29 { 30 int s=1,x=0; 31 char ch=getchar(); 32 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 33 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 34 return x*s; 35 } 36 struct node 37 { 38 ll sum,tagc,tagj; 39 node(){sum=0,tagc=1,tagj=0;} 40 }T[MAXN*4]; 41 int a[MAXN]; 42 inline void push_up(int p) 43 { 44 T[p].sum=(T[ls(p)].sum+T[rs(p)].sum)%P; 45 } 46 inline void build(int p,int l,int r) 47 { 48 if(l==r) 49 { 50 T[p].sum=a[l]; 51 return ; 52 } 53 int mid=(l+r)>>1; 54 build(ls(p),l,mid); 55 build(rs(p),mid+1,r); 56 push_up(p); 57 } 58 inline void push_down(int p,int l,int r) 59 { 60 if(T[p].tagc==1&&T[p].tagj==0) return; 61 T[ls(p)].tagc=(T[ls(p)].tagc*T[p].tagc)%P,T[rs(p)].tagc=(T[rs(p)].tagc*T[p].tagc)%P; 62 T[ls(p)].tagj=(T[ls(p)].tagj*T[p].tagc)%P,T[rs(p)].tagj=(T[rs(p)].tagj*T[p].tagc)%P; 63 T[ls(p)].sum=(T[ls(p)].sum*T[p].tagc)%P,T[rs(p)].sum=(T[rs(p)].sum*T[p].tagc)%P; 64 T[p].tagc=1; 65 int mid=(l+r)>>1; 66 T[ls(p)].tagj=(T[ls(p)].tagj+T[p].tagj)%P,T[rs(p)].tagj=(T[rs(p)].tagj+T[p].tagj)%P; 67 T[ls(p)].sum=(T[ls(p)].sum+(mid-l+1)*T[p].tagj)%P,T[rs(p)].sum=(T[rs(p)].sum+(r-mid)*T[p].tagj)%P; 68 T[p].tagj=0; 69 } 70 inline void update_c(int p,int l,int r,int nl,int nr,int k) 71 { 72 if(nl<=l&&nr>=r) 73 { 74 T[p].sum=(T[p].sum*k)%P; 75 T[p].tagc=(T[p].tagc*k)%P; 76 T[p].tagj=(T[p].tagj*k)%P; 77 return; 78 } 79 int mid=(l+r)>>1; 80 push_down(p,l,r); 81 if(nl<=mid) update_c(ls(p),l,mid,nl,nr,k); 82 if(nr>=mid+1) update_c(rs(p),mid+1,r,nl,nr,k); 83 push_up(p); 84 } 85 inline void update_j(int p,int l,int r,int nl,int nr,int k) 86 { 87 if(nl<=l&&nr>=r) 88 { 89 T[p].tagj=(T[p].tagj+k)%P; 90 T[p].sum=(T[p].sum+(r-l+1)*k)%P; 91 return; 92 } 93 int mid=(l+r)>>1; 94 push_down(p,l,r); 95 if(nl<=mid) update_j(ls(p),l,mid,nl,nr,k); 96 if(nr>=mid+1) update_j(rs(p),mid+1,r,nl,nr,k); 97 push_up(p); 98 } 99 ll query(int p,int l,int r,int nl,int nr) 100 { 101 ll ans=0; 102 if(nl<=l&&nr>=r) return T[p].sum%P; 103 int mid=(l+r)>>1; 104 push_down(p,l,r); 105 if(nl<=mid) ans=(ans+query(ls(p),l,mid,nl,nr))%P; 106 if(nr>=mid+1) ans=(ans+query(rs(p),mid+1,r,nl,nr))%P; 107 return ans; 108 } 109 int main() 110 { 111 N=read(),M=read(),P=read(); 112 for(int i=1;i<=N;++i) a[i]=read(); 113 build(1,1,N); 114 int opt,x,y,k; 115 while(M--) 116 { 117 opt=read(),x=read(),y=read(); 118 if(opt==1) 119 { 120 k=read(); 121 update_c(1,1,N,x,y,k); 122 } 123 else if(opt==2) 124 { 125 k=read(); 126 update_j(1,1,N,x,y,k); 127 } 128 else 129 cout<<query(1,1,N,x,y)<<endl; 130 //for(int i=1;i<=N;++i) 131 //cout<<query(1,1,N,i,i)<<' '<<endl; 132 } 133 }
牵扯到了计算几何,线段树很神奇。题目有多组数据,所以每次建树的时候要记得把懒标记给清零。
维护向量
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(n) (n<<1) 24 #define rs(n) (n<<1|1) 25 #define eps 1e-9 26 using namespace std; 27 const int MAXN=1e4+10; 28 struct node 29 { 30 double x,y; 31 int add;//lazy tag 32 node(){x=0.0,y=0.0,add=0;} 33 }T[MAXN<<2]; 34 int ang[MAXN]; 35 inline void push_up(int p) 36 { 37 T[p].x=T[rs(p)].x+T[ls(p)].x; 38 T[p].y=T[rs(p)].y+T[ls(p)].y; 39 } 40 inline void rotate(int p,int angle) 41 { 42 double x=T[p].x,y=T[p].y; 43 double tmp=Pi/180*angle; 44 T[p].x=cos(tmp)*x-sin(tmp)*y; 45 T[p].y=sin(tmp)*x+cos(tmp)*y; 46 } 47 inline void push_down(int p,int l,int r) 48 { 49 if(!T[p].add) return; 50 rotate(ls(p),T[p].add),rotate(rs(p),T[p].add); 51 T[ls(p)].add+=T[p].add,T[rs(p)].add+=T[p].add; 52 T[p].add=0; 53 } 54 inline void build(int p,int l,int r) 55 { 56 if(l==r) 57 { 58 scanf("%lf",&T[p].y); 59 T[p].x=0,T[p].add=0; 60 return; 61 } 62 T[p].add=0;//因为有多组数据,所以非叶结点也要清除懒标记 63 int mid=(l+r)>>1; 64 build(ls(p),l,mid); 65 build(rs(p),mid+1,r); 66 push_up(p); 67 } 68 inline void update(int p,int l,int r,int nl,int nr,int k) 69 { 70 if(nl<=l&&nr>=r) 71 { 72 T[p].add+=k; 73 rotate(p,k); 74 return ; 75 } 76 push_down(p,l,r); 77 int mid=(l+r)>>1; 78 if(nl<=mid) update(ls(p),l,mid,nl,nr,k); 79 if(nr>mid) update(rs(p),mid+1,r,nl,nr,k); 80 push_up(p); 81 } 82 int n,c; 83 int main() 84 { 85 int cnt=0; 86 while(~scanf("%d%d",&n,&c)) 87 { 88 if(cnt++) puts(""); 89 build(1,1,n); 90 for(int i=1;i<=n;++i) 91 ang[i]=180; 92 93 int s,a; 94 while(c--) 95 { 96 scanf("%d%d",&s,&a); 97 int x=(a-ang[s]+360)%360; 98 update(1,1,n,s+1,n,x); 99 ang[s]=a; 100 printf("%.2lf %.2lf ",T[1].x,T[1].y); 101 } 102 } 103 return 0; 104 }
单点修改、区间满足条件的修改、单点查询
维护区间最小值
1 #include<iostream> 2 #include<sstream> 3 #include<fstream> 4 #include<algorithm> 5 #include<cstring> 6 #include<iomanip> 7 #include<cstdlib> 8 #include<cctype> 9 #include<vector> 10 #include<string> 11 #include<cmath> 12 #include<ctime> 13 #include<stack> 14 #include<queue> 15 #include<map> 16 #include<set> 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define random(a,b) (rand()%(b-a+1)+a) 19 #define ll long long 20 #define ull unsigned long long 21 #define e 2.71828182 22 #define Pi acos(-1.0) 23 #define ls(rt) (rt<<1) 24 #define rs(rt) (rt<<1|1) 25 #define INF 0x7fffffff 26 using namespace std; 27 const int MAXN=2e5+5; 28 int a[MAXN],n,q,p,x; 29 int read() 30 { 31 int s=1,x=0; 32 char ch=getchar(); 33 while(!isdigit(ch)) {if(ch=='-') s=-1;ch=getchar();} 34 while(isdigit(ch)) {x=10*x+ch-'0';ch=getchar();} 35 return x*s; 36 } 37 struct node 38 { 39 int Min,tag; 40 }T[MAXN<<2]; 41 inline void push_up(int rt) 42 { 43 T[rt].Min=min(T[ls(rt)].Min,T[rs(rt)].Min); 44 } 45 inline void build(int rt,int l,int r) 46 { 47 if(l==r) 48 { 49 T[rt].Min=a[l]; 50 T[rt].tag=0; 51 return ; 52 } 53 T[rt].tag=0,T[rt].Min=INF; 54 int mid=(l+r)>>1; 55 build(ls(rt),l,mid); 56 build(rs(rt),mid+1,r); 57 push_up(rt); 58 } 59 inline void push_down(int rt,int l,int r) 60 { 61 if(!T[rt].tag) return ; 62 T[ls(rt)].tag=max(T[ls(rt)].tag,T[rt].tag); 63 T[rs(rt)].tag=max(T[rs(rt)].tag,T[rt].tag); 64 T[ls(rt)].Min=max(T[ls(rt)].Min,T[rt].tag); 65 T[rs(rt)].Min=max(T[rs(rt)].Min,T[rt].tag); 66 T[rt].tag=0; 67 } 68 inline void update_single(int rt,int l,int r,int nl,int nr,int k) 69 { 70 //nl==nr 71 if(l==r) 72 { 73 T[rt].Min=k; 74 return; 75 } 76 push_down(rt,l,r); 77 int mid=(l+r)>>1; 78 if(nl<=mid) update_single(ls(rt),l,mid,nl,nr,k); 79 else update_single(rs(rt),mid+1,r,nl,nr,k); 80 push_up(rt); 81 } 82 inline void update_interval(int rt,int k) 83 { 84 if(k<=T[rt].Min) return; 85 T[rt].Min=k; 86 T[rt].tag=max(T[rt].tag,k); 87 } 88 int query_single(int rt,int l,int r,int nl,int nr) 89 { 90 //nl==nr 91 if(l==r) return T[rt].Min; 92 push_down(rt,l,r); 93 int mid=(l+r)>>1; 94 if(nl<=mid) return query_single(ls(rt),l,mid,nl,nr); 95 else return query_single(rs(rt),mid+1,r,nl,nr); 96 } 97 int main() 98 { 99 n=read(); 100 for(int i=1;i<=n;++i) a[i]=read(); 101 build(1,1,n); 102 q=read(); 103 int opt; 104 while(q--) 105 { 106 opt=read(); 107 if(opt==1) 108 { 109 p=read(),x=read(); 110 update_single(1,1,n,p,p,x); 111 } 112 else 113 { 114 x=read(); 115 update_interval(1,x); 116 } 117 } 118 for(int i=1;i<=n;++i) 119 cout<<query_single(1,1,n,i,i)<<' '; 120 }
维护特殊的LIS,每个结点的左端点包含在内
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ls(rt) rt<<1 4 #define rs(rt) rt<<1|1 5 const int MAXN=1e5+5; 6 int n,m; 7 struct node 8 { 9 double Max;//区间最大值 10 int len;//以区间左端点开头的LIS长 11 }T[MAXN<<2]; 12 inline void build(int rt,int l,int r) 13 { 14 T[rt].Max=0.0,T[rt].len=0; 15 if(l==r) return; 16 int mid=(l+r)>>1; 17 build(ls(rt),l,mid); 18 build(rs(rt),mid+1,r); 19 } 20 inline int cal(int rt,int l,int r,double x) 21 { 22 if(l==r) return T[rt].Max>x; 23 int mid=(l+r)>>1; 24 if(T[ls(rt)].Max<=x) return cal(rs(rt),mid+1,r,x); 25 else return T[rt].len-T[ls(rt)].len+cal(ls(rt),l,mid,x); 26 } 27 inline void push_up(int rt,int l,int r) 28 { 29 T[rt].Max=max(T[ls(rt)].Max,T[rs(rt)].Max); 30 int mid=(l+r)>>1; 31 T[rt].len=T[ls(rt)].len+cal(rs(rt),mid+1,r,T[ls(rt)].Max); 32 } 33 inline void update(int rt,int l,int r,int nl,int nr,double x) 34 { 35 if(nl<=l&&nr>=r) 36 { 37 T[rt].Max=x; 38 T[rt].len=1; 39 return; 40 } 41 int mid=(l+r)>>1; 42 if(nl<=mid) update(ls(rt),l,mid,nl,nr,x); 43 if(nr>mid) update(rs(rt),mid+1,r,nl,nr,x); 44 push_up(rt,l,r); 45 } 46 int query(int rt,int l,int r,int nl,int nr) 47 { 48 if(nl<=l&&nr>=r) return T[rt].len; 49 int mid=(l+r)>>1; 50 if(nl<=l) return query(ls(rt),l,mid+1,nl,nr); 51 else return query(rs(rt),mid+1,r,nl,nr); 52 } 53 int main() 54 { 55 cin>>n>>m; 56 int xi,yi; 57 build(1,1,n); 58 while(m--) 59 { 60 cin>>xi>>yi; 61 update(1,1,n,xi,xi,double(yi)/double(xi)); 62 cout<<query(1,1,n,1,n)<<endl;//T[1].len 63 } 64 return 0; 65 }
线段树维护LIS貌似做不到呀
找每一个数的前面比他大的数、小的数,后面比他大的数、小的数。用树状数组也能求。
注意将最后输出结果的数据类型设为long long
题目中说数据不重复,但没说是1~n的排列,所以如果要用下面的式子需要离散化:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ls(p) (p<<1) 4 #define rs(p) (p<<1|1) 5 const int MAXN=1e5+5; 6 struct node1 7 { 8 int val,pos; 9 bool operator < (const node1& a) 10 { 11 return val<a.val; 12 } 13 }a[MAXN]; 14 struct node2 15 { 16 int sum; 17 }T[MAXN<<2]; 18 int t,n,Hash[MAXN]; 19 inline void push_up(int p,int l,int r) 20 { 21 T[p].sum=T[ls(p)].sum+T[rs(p)].sum; 22 } 23 inline void build(int p,int l,int r) 24 { 25 memset(T,0,sizeof(T)); 26 } 27 inline void update(int p,int l,int r,int lr,int x)//single 28 { 29 if(l==r) 30 { 31 T[p].sum=x; 32 return; 33 } 34 int mid=(l+r)>>1; 35 if(lr<=mid) update(ls(p),l,mid,lr,x); 36 else update(rs(p),mid+1,r,lr,x); 37 push_up(p,l,r); 38 } 39 int query(int p,int l,int r,int nl,int nr) 40 { 41 if(nr<nl) return 0; 42 int ans=0; 43 if(nl<=l&&nr>=r) return T[p].sum; 44 int mid=(l+r)>>1; 45 if(nl<=mid) ans+=query(ls(p),l,mid,nl,nr); 46 if(nr>mid) ans+=query(rs(p),mid+1,r,nl,nr); 47 return ans; 48 } 49 int main() 50 { 51 scanf("%d",&t); 52 while(t--) 53 { 54 scanf("%d",&n); 55 build(1,1,n); 56 for(int i=1;i<=n;++i) scanf("%d",&a[i].val),a[i].pos=i; 57 sort(a+1,a+n+1); 58 for(int i=1;i<=n;++i) Hash[a[i].pos]=i; 59 update(1,1,n,Hash[1],1); 60 //for(int i=1;i<=n;++i) cout<<Hash[i]<<' '; 61 int preless=0,pregreat=0,sufless=0,sufgreat=0; 62 long long ans=0; 63 for(int i=2;i<=n-1;++i) 64 { 65 preless=query(1,1,n,1,Hash[i]-1); 66 pregreat=i-1-preless;//query(1,1,n,Hash[i]+1,n); 67 sufless=Hash[i]-1-preless; 68 sufgreat=n-Hash[i]-pregreat; 69 ans+=preless*sufgreat+pregreat*sufless; 70 //cout<<"i: "<<i<<' '; 71 //cout<<"pl: "<<preless<<" pg: "<<pregreat<<" sl: "<<sufless<<" sg: "<<sufgreat<<endl; 72 update(1,1,n,Hash[i],1); 73 } 74 cout<<ans<<endl; 75 } 76 }