您的位置:首页 > 产品设计 > UI/UE

有趣的线段树小集合 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
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: