有趣的线段树小集合 Codeforces Round #250 (Div. 1) D. The Child and Sequence
2017-10-09 23:59
525 查看
D. The Child and Sequence
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.
Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array a[1], a[2], ..., a[n].
Then he should perform a sequence of m operations. An operation can be one of the following:
Print operation l, r. Picks should write down the value of
.
Modulo operation l, r, x. Picks should perform assignment a[i] = a[i] mod x for
each i (l ≤ i ≤ r).
Set operation k, x. Picks should set the value of a[k] to x (in
other words perform an assignment a[k] = x).
Can you help Picks to perform the whole sequence of operations?
Input
The first line of input contains two integer: n, m (1 ≤ n, m ≤ 105).
The second line contains n integers, separated by space:a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) —
initial value of array elements.
Each of the next m lines begins with a number type
.
If type = 1, there will be two integers more in the line: l, r (1 ≤ l ≤ r ≤ n),
which correspond the operation 1.
If type = 2, there will be three integers more in the line: l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 109),
which correspond the operation 2.
If type = 3, there will be two integers more in the line: k, x (1 ≤ k ≤ n; 1 ≤ x ≤ 109),
which correspond the operation 3.
Output
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
Examples
input
output
input
output
Note
Consider the first testcase:
At first, a = {1, 2, 3, 4, 5}.
After operation 1, a = {1, 2, 3, 0, 1}.
After operation 2, a = {1, 2, 5, 0, 1}.
At operation 3, 2 + 5 + 0 + 1 = 8.
After operation 4, a = {1, 2, 2, 0, 1}.
At operation 5, 1 + 2 + 2 = 5.
区间取模,区间求和,单点修改
直接暴力就行 复杂度证明如下
代码:
fread fwrite版
指针版(第一次写指针)
考NOIP模拟时做到的题
题意就是问区间内颜色不同于给出颜色的有多少,并区间覆盖成该颜色
题解如下
证明那段最开始脑瘫,想O(n+m)的分界点跟染色复杂度有什么关系,然后就发现。。每个分界点只被算一次
分块
线段树
time limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
At the children's day, the child came to Picks's house, and messed his house up. Picks was angry at him. A lot of important things were lost, in particular the favorite sequence of Picks.
Fortunately, Picks remembers how to repair the sequence. Initially he should create an integer array a[1], a[2], ..., a[n].
Then he should perform a sequence of m operations. An operation can be one of the following:
Print operation l, r. Picks should write down the value of
.
Modulo operation l, r, x. Picks should perform assignment a[i] = a[i] mod x for
each i (l ≤ i ≤ r).
Set operation k, x. Picks should set the value of a[k] to x (in
other words perform an assignment a[k] = x).
Can you help Picks to perform the whole sequence of operations?
Input
The first line of input contains two integer: n, m (1 ≤ n, m ≤ 105).
The second line contains n integers, separated by space:a[1], a[2], ..., a[n] (1 ≤ a[i] ≤ 109) —
initial value of array elements.
Each of the next m lines begins with a number type
.
If type = 1, there will be two integers more in the line: l, r (1 ≤ l ≤ r ≤ n),
which correspond the operation 1.
If type = 2, there will be three integers more in the line: l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 109),
which correspond the operation 2.
If type = 3, there will be two integers more in the line: k, x (1 ≤ k ≤ n; 1 ≤ x ≤ 109),
which correspond the operation 3.
Output
For each operation 1, please print a line containing the answer. Notice that the answer may exceed the 32-bit integer.
Examples
input
5 5 1 2 3 4 5 2 3 5 4 3 3 5 1 2 5 2 1 3 3 1 1 3
output
8 5
input
10 10 6 9 6 7 6 1 10 10 9 5 1 3 9 2 7 10 9 2 5 10 8 1 4 7 3 3 7 2 7 9 9 1 2 4 1 6 6 1 5 9 3 1 10
output
49 15 23 1 9
Note
Consider the first testcase:
At first, a = {1, 2, 3, 4, 5}.
After operation 1, a = {1, 2, 3, 0, 1}.
After operation 2, a = {1, 2, 5, 0, 1}.
At operation 3, 2 + 5 + 0 + 1 = 8.
After operation 4, a = {1, 2, 2, 0, 1}.
At operation 5, 1 + 2 + 2 = 5.
区间取模,区间求和,单点修改
直接暴力就行 复杂度证明如下
代码:
fread fwrite版
#include<cmath> #include<ctime> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<set> #include<map> using namespace std; typedef long long ll; char xB[1<<15],*xS=xB,*xT=xB; #define getchar() (xS==xT&&(xT=(xS=xB)+fread(xB,1,1<<15,stdin),xS==xT)?0:*xS++) inline int read() { int x=0;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x; } #define OUT 2000000 char Out[OUT],*ou=Out; int Outn[30],Outcnt; inline void print(ll x) { if(!x)*ou++=48; else { for(Outcnt=0;x;x/=10)Outn[++Outcnt]=x%10+48; while(Outcnt)*ou++=Outn[Outcnt--]; } } const int N=100100; int mx[N<<2];ll sum[N<<2],ans ; void build(int k,int l,int r) { if(l==r){mx[k]=sum[k]=read();return ;} int mid=(l+r)>>1; build(k<<1,l,mid);build(k<<1|1,mid+1,r); mx[k]=max(mx[k<<1],mx[k<<1|1]); sum[k]=sum[k<<1]+sum[k<<1|1]; } void modify(int k,int l,int r,int x,int val) { if(l==r){mx[k]=sum[k]=val;return ;} int mid=(l+r)>>1; x<=mid?modify(k<<1,l,mid,x,val):modify(k<<1|1,mid+1,r,x,val); mx[k]=max(mx[k<<1],mx[k<<1|1]); sum[k]=sum[k<<1]+sum[k<<1|1]; } void modify(int k,int l,int r,int x,int y,int mod) { if(mx[k]<mod)return ; if(l==r){mx[k]=sum[k]=mx[k]%mod;return ;} int mid=(l+r)>>1; if(x<=mid)modify(k<<1,l,mid,x,y,mod); if(y>mid)modify(k<<1|1,mid+1,r,x,y,mod); mx[k]=max(mx[k<<1],mx[k<<1|1]); sum[k]=sum[k<<1]+sum[k<<1|1]; } ll query(int k,int l,int r,int x,int y) { if(l>=x&&r<=y)return sum[k]; int mid=(l+r)>>1; if(x>mid)return query(k<<1|1,mid+1,r,x,y); if(y<=mid)return query(k<<1,l,mid,x,y); return query(k<<1|1,mid+1,r,x,y)+query(k<<1,l,mid,x,y); } int main() { int n=read(); register int i,opt,x,y,mod,tot=0,Q=read(); build(1,1,n); while(Q--) { opt=read();x=read();y=read(); switch(opt) { case 1:ans[++tot]=query(1,1,n,x,y);break; case 2:mod=read();modify(1,1,n,x,y,mod);break; case 3:modify(1,1,n,x,y);break; } } for(i=1;i<=tot;++i)print(ans[i]),*ou++='\n'; fwrite(Out,1,ou-Out,stdout); return 0; }
指针版(第一次写指针)
#include<cmath> #include<ctime> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #include<iomanip> #include<vector> #include<string> #include<bitset> #include<queue> #include<set> #include<map> using namespace std; typedef long long ll; #ifdef ONLINE_JUDGE char *TT,*mo,but[(1<<15)+2]; #define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin)),TT==mo)?0:*TT++) #endif inline int read(){ int x=0,c=0,f=1; for(;c<'0'||c>'9';c=getchar())f=c!='-'; for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0'; return f?x:-x; } void print(ll x) {if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');} const int N=100100; struct seg_tree{int mx;ll sum;seg_tree *ls,*rs;}tr[N<<2]; int sz; inline void pushup(seg_tree *k) { k->mx=max(k->ls->mx,k->rs->mx); k->sum=k->ls->sum+k->rs->sum; } void build(seg_tree *k,int l,int r) { if(l==r){k->mx=k->sum=read();return ;} int mid=(l+r)>>1; k->ls=&tr[++sz];k->rs=&tr[++sz]; build(k->ls,l,mid);build(k->rs,mid+1,r); pushup(k); } void modify(seg_tree *k,int l,int r,int x,int val) { if(l==r){k->mx=k->sum=val;return ;} int mid=(l+r)>>1; x<=mid?modify(k->ls,l,mid,x,val):modify(k->rs,mid+1,r,x,val); pushup(k); } void modify(seg_tree *k,int l,int r,int x,int y,int mod) { if(k->mx<ll(mod))return ; if(l==r){k->mx=k->sum=k->mx%mod;return ;} int mid=(l+r)>>1; if(x<=mid)modify(k->ls,l,mid,x,y,mod); if(y>mid)modify(k->rs,mid+1,r,x,y,mod); pushup(k); } ll query(seg_tree *k,int l,int r,int x,int y) { if(l>=x&&r<=y)return k->sum; int mid=(l+r)>>1; if(x>mid)return query(k->rs,mid+1,r,x,y); if(y<=mid)return query(k->ls,l,mid,x,y); return query(k->rs,mid+1,r,x,y)+query(k->ls,l,mid,x,y); } int main() { int n=read();int Q=read(); register int opt,x,y,mod; build(&tr[++sz],1,n); while(Q--) { opt=read();x=read();y=read();//cout<<opt<<endl; switch(opt) { case 1:print(query(&tr[1],1,n,x,y));puts("");break; case 2:mod=read();modify(&tr[1],1,n,x,y,mod);break; case 3:modify(&tr[1],1,n,x,y);break; } } return 0; } /* GGBGGBBGBG 4 */
考NOIP模拟时做到的题
题意就是问区间内颜色不同于给出颜色的有多少,并区间覆盖成该颜色
题解如下
证明那段最开始脑瘫,想O(n+m)的分界点跟染色复杂度有什么关系,然后就发现。。每个分界点只被算一次
分块
#include <cmath> #include <queue> #include <cstdio> #include <iomanip> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #define N 100010 #define ll long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,blk; int a ,belong ,b[350][310],cov[350]; int l[350],r[350]; int T; void re_build(int x) { if(!cov[x])return ; for(int i=1;i<=m;i++) b[x][i]=0; for(int i=l[x];i<=r[x];i++) a[i]=cov[x],b[x][a[i]]++; cov[x]=0; } int main() { n=read(),m=read();blk=sqrt(n); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) { belong[i]=(i-1)/blk+1; if(belong[i]^belong[i-1]) l[belong[i]]=i,r[belong[i-1]]=i-1; } r[belong ]=n,l[belong[1]]=1; for(int i=1;i<=n;i++) b[belong[i]][a[i]]++; T=read(); while(T--) { int x=read(),y=read(); int ret=0; if(belong[x]==belong[y]) { re_build(belong[x]); for(int i=x+1;i<=y;i++) { if(a[i]==a[x])ret++; b[belong[x]][a[i]]--,b[belong[x]][a[x]]++; a[i]=a[x]; } printf("%d\n",ret); continue; } re_build(belong[x]),re_build(belong[y]); for(int i=x+1;i<=r[belong[x]];i++) { if(a[i]==a[x])ret++; b[belong[x]][a[i]]--,b[belong[x]][a[i]=a[x]]++; } for(int i=l[belong[y]];i<=y;i++) { if(a[i]==a[x])ret++; b[belong[y]][a[i]]--,b[belong[y]][a[i]=a[x]]++; } for(int i=belong[x]+1;i<=belong[y]-1;i++) { if(cov[i]) { if(cov[i]==a[x]) ret+=r[i]-l[i]+1; else cov[i]=a[x]; } else ret+=b[i][a[x]],cov[i]=a[x]; } printf("%d\n",ret); } } /* 2 2 1 2 2 1 2 1 2 */
线段树
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<cstdlib> #include<string> #include<queue> #include<vector> #define INT_MAX 2147483647 #define INT_MIN (-INT_MAX-1) #define N 100010 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,a ,ans,t; struct SEGTREENOTE { int val,tag,pos; }segtree[4*N+10]; inline void build(int root,int l,int r) { if(l==r) { segtree[root].val=a[l]; segtree[root].pos=l; return; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); if(segtree[root<<1].val==segtree[root<<1|1].val)segtree[root].val=segtree[root<<1].val; } inline void pushdown(int root) { if(segtree[root].tag) { segtree[root<<1].val=segtree[root].tag; segtree[root<<1|1].val=segtree[root].tag; segtree[root<<1].tag=segtree[root].tag; segtree[root<<1|1].tag=segtree[root].tag; segtree[root].tag=0; } } inline void pushup(int root) { if(segtree[root<<1].val==segtree[root<<1|1].val)segtree[root].val=segtree[root<<1].val; else segtree[root].val=0; } inline int num(int root,int l,int r,int k) { if(segtree[root].val==k)return r-l+1; //cout<<segtree[root].val<<' '<<k; //if(l==r)return 0; if(segtree[root].val&&segtree[root].val!=k)return 0; {int mid=(l+r)>>1; return num(root<<1,l,mid,k)+num(root<<1|1,mid+1,r,k);} } inline void change(int root,int x,int y,int l,int r,int k) { if(l>y||r<x)return; if(l>=x&&r<=y) { ans+=num(root,l,r,k); //cout<<segtree[root].val; segtree[root].val=k; segtree[root].tag=k; return; } int mid=(l+r)>>1; pushdown(root); change(root<<1,x,y,l,mid,k); change(root<<1|1,x,y,mid+1,r,k); pushup(root); } inline int query(int root,int x,int l,int r) { if(l>x||r<x)return INT_MAX; if(x>=l&&x<=r) { if(segtree[root].val){return segtree[root].val;} } int mid=(l+r)>>1; return min(query(root<<1,x,l,mid),query(root<<1|1,x,mid+1,r)); } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); build(1,1,n); t=read(); while(t--) { int x,y; ans=0; x=read();y=read(); change(1,x+1,y,1,n,query(1,x,1,n)); printf("%d\n",ans); } }
相关文章推荐
- Codeforces Round #250 (Div. 1) D. The Child and Sequence (线段树)
- [均摊 平衡树 || 线段树] Codeforces 438D #250 (Div. 1) D. The Child and Sequence
- Codeforces Round #250 (Div. 1) D. The Child and Sequence(线段树暴力)
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树
- Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间求和+点修改+区间取模
- [均摊复杂度线段树]Codeforces 438D. The Child and Sequence
- CF(438D) The Child and Sequence(线段树)
- codeforces 438D. The Child and Sequence(线段树)
- CF(438D) The Child and Sequence(线段树)
- Codeforces Round #250 (Div. 1) D. The Child and Sequence
- Codeforces Round #250 (Div. 1) D. The Child and Sequence
- Codefroces 438D. The Child and Sequence(线段树)
- Codeforces Round #250 (Div. 1) D. The Child and Sequence
- Codeforces Round #250 (Div. 1) D. The Child and Sequence
- The Child and Sequence(线段树)
- 线段树【CF620E】The Child and Sequence
- Codeforces Round #250 (Div. 2)C. The Child and Toy(贪心)
- Codeforce 438D-The Child and Sequence
- Codeforces Round #250 Div. 2(C.The Child and Toy)