1. 程式人生 > >Codeforces Round #321 (Div. 2) E - Kefa and Watch

Codeforces Round #321 (Div. 2) E - Kefa and Watch

back fin put 我們 esp bool cond can push_back

題目大意:給你一個由0-9組成的字符串,有m個詢問,兩種操作,第一種將l到r的字符全部變成c,第二種問l到r這段

字符串的循環節是不是d。

思路:首先我們要知道怎麽判斷字符串的循環節的長度是不是d,如果這個字符串小於等於d,那麽肯定是的,否則,如果l 到 r-d

和l+d 到 r 這兩段字符串則循環節的長度是d,反之不是。 然後我們就用線段樹維護區間字符串哈希值就好啦。

#include<bits/stdc++.h>
#define read(x) scanf("%d",&x)
#define lread(x) scanf("%lld",&x)
#define pii pair<int,int>
#define
fi first #define se second #define pb push_back #define mk make_pair using namespace std; typedef long long ll; const int N=1e5+7; const int inf=0x3f3f3f3f; const ll INF=0x3f3f3f3f3f3f3f3f; const int mod=1998030377; const int base=10; int n,m,k; ll b[N],sum[N]; struct seg_tree { struct node { ll hs;
int l,r,lazy; }a[N<<2]; void up(int l,int r,int rt) { int mid=(l+r)>>1; int len=r-mid; a[rt].hs=(a[rt<<1].hs*b[len]+a[rt<<1|1].hs)%mod; } void down(int l,int r,int rt) { if(a[rt].lazy==-1) return; int c=a[rt].lazy; a[rt].lazy=-1
; a[rt<<1].lazy=a[rt<<1|1].lazy=c; int mid=(l+r)>>1; a[rt<<1].hs=c*sum[mid-l]%mod; a[rt<<1|1].hs=c*sum[r-mid-1]%mod; } void build(int l,int r,int rt) { a[rt].l=l; a[rt].r=r; a[rt].lazy=-1; if(l==r) { int x; scanf("%1d",&x); a[rt].hs=x; return; } int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); up(l,r,rt); } void updata(int L,int R,int c,int rt) { int l=a[rt].l,r=a[rt].r; if(l>=L && r<=R) { a[rt].lazy=c; a[rt].hs=c*(sum[r-l])%mod; return; } down(l,r,rt); int mid=(l+r)>>1; if(L<=mid) updata(L,R,c,rt<<1); if(R>mid) updata(L,R,c,rt<<1|1); up(l,r,rt); } ll query(int L,int R,int rt) { int l=a[rt].l,r=a[rt].r; if(l>=L && r<=R) return a[rt].hs; down(l,r,rt); int mid=(l+r)>>1; ll ans=0; int len=max(0,min(R,r)-mid); if(R>mid) ans=query(L,R,rt<<1|1); if(L<=mid) ans=(ans+query(L,R,rt<<1)*b[len])%mod; return ans; } }seg; bool check(int l,int r,int d) { if(r-l+1<=d) return true; ll hs1=seg.query(l,r-d,1); ll hs2=seg.query(l+d,r,1); return hs1==hs2; } void init() { b[0]=1; sum[0]=1; for(int i=1;i<N;i++) b[i]=b[i-1]*base%mod; for(int i=1;i<N;i++) sum[i]=(sum[i-1]+b[i])%mod; } int main() { init(); read(n); read(m); read(k); seg.build(1,n,1); for(int i=1;i<=m+k;i++) { int op,l,r; read(op); read(l); read(r); if(op==1) { int c; read(c); seg.updata(l,r,c,1); } else { int d; read(d); if(check(l,r,d)) puts("YES"); else puts("NO"); } } return 0; }

Codeforces Round #321 (Div. 2) E - Kefa and Watch