Preface : I block due to very low levels, so there may be a variety of wonderful wrong, please point it out to see, be grateful.
(Basically hereDifficultThe block, provided the cheese I was too lazy to write)
FAQ
Q: What partitioning is?
A: a high-end violence, specifically, is to ask and try to modify the degree of complexity in equal shares, such questions are asked in general higher (modified) complexity (such as \ (\ Theta (n) \ ) ), modified (ask) low complexity (such as \ (\ Theta (1) \) ), if both reach the \ (\ Theta (\ sqrt the n-) \) , the problem can be more efficient solution.
Q: block only do it?
A: In addition to general questions, there will be a pure block \ (Poly log \) practice ...
Sei题
CF1178G
Meaning of the questions:
Given a rooted tree, there are two numbers for each point \ (a_i, b_i \ in [ -5000,5000] \) is defined as the weight for
\ [\ vert \ sum_ {w \ in R (v)} a_w \ Vert \ CDOT \ Vert \ sum_ {W \ in R & lt (V)} B_W \ Vert \]
( \ (R & lt (X) \) is defined as \ (X \) all nodes to the root node of simple paths)
Two operations
1 v x:\(a_v +=x (x>0)\)
Qiuzi tree: 2 V \ (V \) values in the maximum weight
\ (\ Text {limit} n \ the 100000 \)
solution:
Observed \ (B_i \) actually fixed it can be pretreated
The answer is \ (max \ {- min (V_I), V_I \} \) (also negative process)
Then we discovered that in fact is the dynamic demand \ (kx + b \) is the maximum value ( \ (B \ rightarrow K, A \ rightarrow X, A'B '\ rightarrow B \) initial weight is constant)
In fact, it is the largest cut intercept on the convex hull
Then we can follow the \ (DFN \) into blocks, each block marked with the intermediate offset \ (Tag \) (moved back position of the convex hull of the Tag), the reconstructed block violent corner (initial value \ (+ B * X = \) ), found \ (Tag \) monocytogenes, so does not require direct violence moves back half enough.
Code is relatively clear
//Love and Freedom.
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 20021225
#define N 200010
#define BS 505
using namespace std;
int read()
{
int s=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return f*s;
}
struct edge{int to,lt;}e[N<<1];
int n,m,q;
int in[N],cnt,dfn[N],idfn[N],sz[N],a[N],b[N],A[N],B[N];
void add(int x,int y)
{
e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;
e[++cnt].to=x; e[cnt].lt=in[y]; in[y]=cnt;
}
struct poi
{
ll x,y;
poi(){}
poi(ll _x,ll _y){x=_x,y=_y;}
ll val(int _x){return x*_x+y;}
};
poi operator-(poi a,poi b){return poi(a.x-b.x,a.y-b.y);}
ll cross(poi a,poi b){return a.x*b.y-a.y*b.x;}
struct que
{
poi q[BS]; int hd,tl;
void init(){hd=1; tl=0;}
void push(poi a){q[++tl]=a;}
void addpoi(ll x,ll y)
{
poi ins=poi(x,y);
while(hd<tl && cross(q[tl]-q[tl-1],ins-q[tl-1])>=0) tl--; push(ins);
}
ll query(int x)
{
ll ans=-1e18;
while(hd<tl && q[hd].val(x)<=q[hd+1].val(x)) hd++; if(hd<=tl) ans=max(ans,q[hd].val(x));
return ans;
}
};
bool cmp(int x,int y){return B[x]<B[y];}
struct block
{
que up,dn; int l,r,sz,num[BS],tag;
ll query(){return max(up.query(tag),dn.query(tag));}
void build()
{
up.init(); dn.init(); sz=r-l+1;
for(int i=l;i<=r;i++) num[i-l+1]=i;
sort(num+1,num+sz+1,cmp);
for(int i=1;i<=sz;i++)
up.addpoi(B[num[i]],1ll*A[num[i]]*B[num[i]]);
reverse(num+1,num+sz+1);
for(int i=1;i<=sz;i++)
dn.addpoi(-B[num[i]],-1ll*A[num[i]]*B[num[i]]);
}
}kk[BS];
int tms;
void dfs(int x,int fr)
{
sz[x]=1; dfn[x]=++tms; idfn[tms]=x;
a[x]+=a[fr]; b[x]+=b[fr];
for(int i=in[x];i;i=e[i].lt)
{
int y=e[i].to; if(y==fr) continue;
dfs(y,x); sz[x]+=sz[y];
}
}
int bel[N];
void init()
{
m=sqrt(n); int bk=(n+m-1)/m;
for(int i=1;i<=bk;i++)
{
kk[i].l=(i-1)*m+1; kk[i].r=min(i*m,n);
for(int j=kk[i].l;j<=kk[i].r;j++)
bel[j]=i;
kk[i].build();
}
}
void modify(int l,int r,int v)
{
if(bel[l]==bel[r])
{
for(int i=l;i<=r;i++) A[i]+=v;
kk[bel[l]].build(); return;
}
for(int i=l;i<=kk[bel[l]].r;i++) A[i]+=v; kk[bel[l]].build();
for(int i=kk[bel[r]].l;i<=r;i++) A[i]+=v; kk[bel[r]].build();
for(int i=bel[l]+1;i<bel[r];i++) kk[i].tag+=v;
}
ll query(int l,int r)
{
ll ans=-1e18;
if(bel[l]==bel[r])
{
for(int i=l;i<=r;i++)
ans=max(ans,1ll*abs(A[i]+kk[bel[l]].tag)*B[i]);
return ans;
}
for(int i=l;i<=kk[bel[l]].r;i++)
ans=max(ans,1ll*abs(A[i]+kk[bel[l]].tag)*B[i]);
for(int i=kk[bel[r]].l;i<=r;i++)
ans=max(ans,1ll*abs(A[i]+kk[bel[r]].tag)*B[i]);
for(int i=bel[l]+1;i<bel[r];i++)
ans=max(ans,kk[i].query());
return ans;
}
int main()
{
n=read(),q=read();
for(int i=2;i<=n;i++) add(read(),i);
for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++) b[i]=read();
dfs(1,0);
for(int i=1;i<=n;i++) A[i]=a[idfn[i]],B[i]=abs(b[idfn[i]]);
init();
while(q--)
{
int ty=read(),x=read();
if(ty==1)
{
int v=read();
modify(dfn[x],dfn[x]+sz[x]-1,v);
}
else
{
printf("%I64d\n",query(dfn[x],dfn[x]+sz[x]-1));
}
}
return 0;
}
[Ynoi2018] In the end what to do? There are no empty? You can save it?
\ (\ Color {Red} {\ text {warning}} \) : This code is no card in the past, only to ensure accuracy.
Meaning of the questions:
Interval plus (positive integer), the largest sub-segment and range.
\(\text{limit}:n\leq 100000\)
solution:
First consider the overall situation to do maintenance function \ (f (x) \) represents \ (+ x \) answer, obviously a convex hull (lower boss)
Similar questions on maintenance \ (tag \) and then we find that we can not maintain the convex hull blocks fast
Consider how to engage the convex hull
We divide and conquer \ ((l, r) \ ) apparently \ ((l, mid) \ ) and \ ((mid, r) \ ) convex hull can count recursion
Across \ (mid \) the convex hull of demand is not good, but we can think of a single point of modification of the maximum range of sub-segments and how to do it, we can combine the left section of the largest and suffix / prefix and the right section of the largest (apparently two a is convex) and the combined package has a convexClever but uselessMinkowski and (what is it you do not poke this blog post to learn about) do \ (\ Theta (n) \ ) merger.
Then after you have finished T fly friends ha ha
What specific optimization can see the fairy blog to learn about
Card can be used not in the past this problem to verify the correctness
(How I wrote it a few days ago when the permissions problem, today it is not a question mark ?? black face .jpg)
//Love and Freedom.
#pragma GCC optimize(3)
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define N 100010
#define B 110
#define INF (1ll<<48)
using namespace std;
int read()
{
int s=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return f*s;
}
struct poi
{
ll x,y;
poi(){}
poi(ll _x,ll _y){x=_x,y=_y;}
};
poi operator+(poi a,poi b){return poi(a.x+b.x,a.y+b.y);}
poi operator-(poi a,poi b){return poi(a.x-b.x,a.y-b.y);}
ll cross(poi a,poi b){return a.x*b.y-a.y*b.x;}
struct data{ll l,r,ans,sum;};
data operator+(data a,data b)
{
data ans;
ans.l=max(a.l,a.sum+b.l);
ans.r=max(b.r,b.sum+a.r);
ans.ans=max(a.ans,max(b.ans,a.r+b.l));
ans.sum=a.sum+b.sum;
return ans;
}
void gethull(poi *st,int &top)
{
int rem=top; top=1;
for(int i=2;i<=rem;i++)
{
while(top>1 && cross(st[i]-st[top-1],st[top]-st[top-1])<=0) top--;
st[++top]=st[i];
}
}
poi tmp[B+10]; int n,m;
void insert(poi a){tmp[a.x].y=max(tmp[a.x].y,a.y);}
struct block
{
int l,r,sz; poi pre[B+10],suf[B+10],ans[B+10]; ll a[B+10];
data val; ll tag; bool flag; int lsz; int s1,s2,s3,p1,p2,p3;
int brute(int l,int r) // (l,r]
{
ll sum=0; for(int i=l+1;i<=r;i++) sum+=a[i],ans[i]=poi(i-l,sum);
for(int i=l+2;i<=r;i++)
{
sum=0; for(int j=0;i+j<=r;j++)
sum+=a[i+j],ans[l+j+1].y=max(ans[l+j+1].y,sum);
}
s3=r-l; gethull(ans+l,s3); return s3;
}
ll getval(poi a){return a.y+a.x*tag;}
int solve(int l,int r) // (l,r]
{
if(r-l<lsz) return 0; if(r-l<17) return brute(l,r);
int mid=l+r>>1;
int ls=solve(l,mid),rs=solve(mid,r);
for(int i=1;i<=r-l;i++) tmp[i]=poi(i,-INF);
for(int i=l+1;i<=l+ls;i++) insert(ans[i]);
for(int i=mid+1;i<=mid+rs;i++) insert(ans[i]);
ll sum=0; s1=0; for(int i=mid+1;i<=r;i++) s1++,sum+=a[i],pre[s1]=poi(s1,sum); gethull(pre,s1);
sum=0; s2=0; for(int i=mid;i>l;i--) s2++,sum+=a[i],suf[s2]=poi(s2,sum); gethull(suf,s2);
int w1=1,w2=1; insert(pre[w1]+suf[w2]);
while(w1!=s1&&w2!=s2)
{
if(cross(pre[w1+1]+suf[w2]-pre[w1]-suf[w2],pre[w1]+suf[w2+1]-pre[w1]-suf[w2])>=0) w2++;
else w1++; insert(pre[w1]+suf[w2]);
}
while(w1!=s1) w1++,insert(pre[w1]+suf[w2]);
while(w2!=s2) w2++,insert(pre[w1]+suf[w2]);
gethull(tmp,s3=r-l); for(int i=1;i<=s3;i++) ans[l+i]=tmp[i];
return s3;
}
void moveon(poi *a,int &p,int &s)
{
while(p<s) if(getval(a[p])<=getval(a[p+1])) p++;
else return;
}
void recons()
{
if(tag) for(int i=1;i<=sz;i++) a[i]+=tag; tag=0;
if(!flag){flag=1; for(int i=1;i<=sz;i++) flag&=(a[i]>=0);}
if(flag){val.sum=0; for(int i=1;i<=sz;i++) val.sum+=a[i]; val.l=val.r=val.ans=val.sum; return;}
lsz=ans[p3].x; solve(0,sz);
ll sum=0; s1=0; for(int i=1;i<=sz;i++) s1++,sum+=a[i],pre[s1]=poi(s1,sum); gethull(pre,s1);
sum=0; s2=0; for(int i=sz;i;i--) s2++,sum+=a[i],suf[s2]=poi(s2,sum); gethull(suf,s2);
p1=p2=p3=1; moveon(pre,p1,s1); moveon(suf,p2,s2); moveon(ans,p3,s3);
flag&=(p1==s1)&&(p2==s2)&&(p3==s3);
val=(data){max(pre[p1].y,0ll),max(suf[p2].y,0ll),max(ans[p3].y,0ll),sum};
}
void modify(int x)
{
if(flag){tag+=x; val.sum+=x*sz; val.l=val.r=val.ans=val.sum; return;}
tag+=x; moveon(pre,p1,s1); moveon(suf,p2,s2); moveon(ans,p3,s3);
val=(data){max(0ll,getval(pre[p1])),max(0ll,getval(suf[p2])),max(0ll,getval(ans[p3])),val.sum+x*sz};
}
data calc(int l,int r) // [l,r]
{
data wei=(data){0,0,0,0}; ll sum=0;
for(int i=l;i<=r;i++) sum+=a[i]+tag; wei.sum=sum; sum=0;
for(int i=l;i<=r;i++) sum+=a[i]+tag,wei.l=max(wei.l,sum); sum=0;
for(int i=r;i>=l;i--) sum+=a[i]+tag,wei.r=max(wei.r,sum); sum=0;
for(int i=l;i<=r;i++)
{
sum+=a[i]+tag; if(sum<0) sum=0;
wei.ans=max(wei.ans,sum);
}
return wei;
}
ll getans(int l,int r)
{
ll sum=0; ll ans=0;
for(int i=l;i<=r;i++)
{
sum+=a[i]+tag; if(sum<0) sum=0;
ans=max(sum,ans);
}
return ans;
}
}blo[(N/B)+1]; int bel[N];
void modify(int l,int r,int x)
{
int id=bel[l],fr=blo[id].l;
if(bel[l]==bel[r])
{
for(int i=l;i<=r;i++)
blo[id].a[i-fr]+=x;
blo[id].recons();
return;
}
for(int i=l;i<=blo[id].r;i++) blo[id].a[i-fr]+=x; blo[id].recons(); id=bel[r],fr=blo[id].l;
for(int i=blo[id].l+1;i<=r;i++) blo[id].a[i-fr]+=x; blo[id].recons();
for(int i=bel[l]+1;i<bel[r];i++) blo[i].modify(x);
}
ll query(int l,int r)
{
int id=bel[l],fr=blo[id].l;
if(bel[l]==bel[r]) return blo[id].getans(l-fr,r-fr);
data qwq=blo[id].calc(l-fr,blo[id].r-fr);
for(int i=bel[l]+1;i<bel[r];i++) qwq=qwq+blo[i].val;
qwq=qwq+blo[bel[r]].calc(1,r-blo[bel[r]].l);
return qwq.ans;
}
char ch[10];
int main()
{
n=read(),m=read();
for(int i=0,id=0;i<=n;i+=B,id++)
{
for(int j=1;j<=B&&i+j<=n;j++) blo[id].a[j]=read(),bel[i+j]=id;
blo[id].sz=min(n-i,B); blo[id].l=i; blo[id].r=i+B; blo[id].recons();
}
while(m--)
{
scanf("%s",ch+1); int l=read(),r=read();
if(ch[1]=='A') modify(l,r,read());
else printf("%lld\n",query(l,r));
}
return 0;
}
Interval reverse order
This simple (
solution:
Maintenance to the prefix / suffix to reverse block number, then the corners like violence
//Love and Freedom.
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 20021225
#define N 51000
#define B 200
using namespace std;
int read()
{
int s=0,f=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return f*s;
}
int tmp[N];
int solve(int *a,int n)
{
if(n<=1) return 0;
int s1=n>>1,s2=n-s1,ans=solve(a,s1)+solve(a+s1,s2),l=0,r=0,sz=0;
while(l<s1&&r<s2)
{
if(a[l]>a[s1+r]) tmp[sz++]=a[r+s1],r++;
else tmp[sz++]=a[l++],ans+=r;
}
while(l<s1) tmp[sz++]=a[l++],ans+=s2;
while(r<s2) tmp[sz++]=a[s1+r],r++;
for(int i=0;i<sz;i++) a[i]=tmp[i];
return ans;
}
int suf[N][(N/B)+1],pre[N][(N/B)+1]; int a[N+10],n,v[N+10];
int cnt[N]; int bel[N],lb[(N/B)+1],rb[(N/B)+1],blo[(N/B)+1],sz[(N/B)+1],bc,rem[N+10];
int main()
{
n=read(); for(int i=1;i<=n;i++) v[i]=a[i]=read();
sort(v+1,v+n+1); int nn=unique(v+1,v+n+1)-v;
for(int i=1;i<=n;i++) rem[i]=a[i]=lower_bound(v+1,v+nn,a[i])-v;
for(int i=1,id=1;i<=n;i+=B,id++)
{
for(int j=0;j<B;j++) cnt[a[i+j]]++,bel[i+j]=id;
for(int j=1;j<=nn;j++) cnt[i]+=cnt[i-1];
for(int j=1;j<i;j++) pre[j][id]=pre[j-1][id]+cnt[a[j]-1];
lb[id]=i; rb[id]=min(n,i+B-1); sz[id]=rb[id]-lb[id]+1; blo[id]=solve(a+i,sz[id]);
bc=id; for(int j=1;j<=nn;j++) cnt[j]=0;
}
for(int i=bc;i;i--)
{
int l=lb[i],r=rb[i];
for(int j=l;j<=r;j++) cnt[a[j]]++;
for(int j=1;j<=nn;j++) cnt[j]+=cnt[j-1];
for(int j=r+1;j<=n;j++) suf[j][i]=suf[j+1][i]+(sz[i]-cnt[a[j]]);
for(int j=1;j<=nn;j++) cnt[j]=0;
}
int m=read(),lastans=0;
while(m--)
{
int l=read()^lastans,r=read()^lastans;
if(bel[l]==bel[r])
{
for(int i=l;i<=r;i++) a[i]=rem[i];
printf("%d\n",lastans=solve(a+l,r-l+1));
continue;
}
int lid=bel[l],rid=bel[r],tot=0;
for(int i=l;i<=rb[lid];i++) a[tot++]=rem[i];
for(int i=lb[rid];i<=r;i++) a[tot++]=rem[i];
int ans=solve(a,tot);
for(int i=lid+1;i<rid;i++) ans+=pre[r][i]-pre[l-1][i]+suf[l][i]-suf[r+1][i]+blo[i];
printf("%d\n",lastans=ans);
}
return 0;
}
I seem to 3 md wrote three days? ? 8 really understand (
\ (\ Color {Red} {\ text {warning}} \) : The remaining issues did not just write the possibility of a great read it so wrong
Mo secondary Offline team
Consider \ ([l, r] \ ) to \ ([l ', r' ] \) Development
For the right to expand \ (r \) answer increment is \ (query (1, r- 1) -query (1, l-1) \)
Also left by suffixes on it
It may be converted to the query \ ([1, r] \ ) in \ (> s [r] \ ) number and query \ ([1, r] \ ) in \ (> s [a, b ] \ ) number, which may be two \ (\ Theta (1) \ ) answer, the total complexity of the \ (\ Theta (n \ sqrt n) \)
Premise: meet Subtractivity
Block 14 (Hard Ver.)
Meaning of the questions:
There \ (n-\) number \ (a_i \)
Each time a given interval \ ([l, r] \ ) how the query interval tuple \ ((i, j) \ ) satisfies \ (a_i \) is \ (a_j \) multiple
\(\text{limit}: n,a_i \le 100000\)
solution:
Secondary offline Mo teams, converted to the following questions
Query \ ([1, r] \ ) is \ (S [R & lt] \) / \ (S [A, B] \) number divisor / multiple
Multiple enumerator can be directly obtained about the number, about a single number may be pretreated, the only check a submultiple of the whole block.
No consideration about the number of the partition, \ (> \} n-sqrt {\) may enumerate multiple scan lines, \ (\ Le \ n-sqrt \) may be enumerated first, and then to engage and direct operator prefix, consider interval to this stuff only \ (\ sqrt n \) so that \ (\ Theta (\ sqrt n ^ 3) \) or \ (\ Theta (n \ sqrt n) \)
· Change every day, love running
Ah look at this I'm too lazy to write it
BZOJ5145
CF896E
UOJ 33
Uoj435
UOJ337
The above is a list of cuckoo