점분 치 와 점분 수
254002 단어 데이터 구조
토로
제목
충격파
구유
작년 에 은퇴 시 켜 준 좋 은 물건.한 문 제 를 쓰 고 나 면 내 가 이미 동태 적 으로 분 리 를 할 수 있다 고 생각 하 는 나 는 정말 too young too simple, sometimes naive. 지금 은 적어도 작년 처럼 머리 를 쥐 어 뜯 고 템 플 릿 을 쓰 지 않 는 다.그러나 거 위 는 나의 작은 bug 더미 에 영향 을 주지 않 는 다.이 배열 은 경 계 를 넘 었 습 니 다. 그곳 은 비우 지 않 았 습 니 다. 그곳 은 변수 가 바 뀌 었 습 니 다.
제목.
[IOI2011]Race
내 마음 을 무 너 뜨리 는 좋 은 본보기.더 이상 평범 할 수 없 는 분할 치료 양식 이지 만 거 위 는 죽어도 조절 할 수 없다.코드 를 재 구성 하 는 것 은 그래도 마지막 에 어떻게 고 치 는 지 나 도 어디로 가 야 할 지 모 르 겠 어.대략 d [0] 는 n 과 tot - sz [x] 로 부 여 됩 니 다.이 거 교 는 아들 과 나의 sz 의 크기 관 계 를 직접 판단 하여 아들 의 실제 sz 를 얻 었 다.どこでもドア
//Achen
#include
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=200007,M=1000007;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,ans,K,d[M];
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
void add(int u,int v,int w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}
int RT,sz[N],msz[N],vis[N];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[x]<msz[RT]) RT=x;
}
int sta[N],R[N],H[N],top;
void dfs(int x,int fa,int now,int cc) {
if(now>K) return;
sta[++top]=x;
R[x]=cc; H[x]=now;
ans=min(ans,d[K-now]+cc);
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,now+val[i],cc+1);
}
void solve(int x,int tot) {
vis[x]=1; int pr=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
dfs(to[i],x,val[i],1);
For(i,pr+1,top) d[H[sta[i]]]=min(d[H[sta[i]]],R[sta[i]]); pr=top;
}
while(top) d[H[sta[top--]]]=n; d[0]=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
RT=0; int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
get_root(to[i],x,lsz); solve(RT,lsz);
}
}
int main() {
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
read(n); read(K);
For(i,1,K) d[i]=n; ans=n;
For(i,2,n) {
int u,v,w;
read(u); read(v); read(w);
add(u+1,v+1,w);
}
get_root(1,0,n); solve(1,n);
if(ans==n) ans=-1;
printf("%d
",ans);
Formylove;
}
cf716 E. Digit Tree
............................................................................................
경 로 를 반 으로 나 누 면 l v 는 8727 ° 1 0 d e p r + r v. 1. ( m o d p ) lv*10^{dep_r}+rv \equiv 0\ (mod\ p) lv∗10depr+rv≡0 (mod p) 전형 점.(p, 10) = 1 exgcd 로 10 의 역 원 을 구하 라 고 합 니 다.
//Achen
#include
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=100007;
typedef long long LL;
typedef double db;
using namespace std;
int n,p;
LL ans,pr[N],prinv[N];
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
void add(int u,int v,int w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}
int RT,sz[N],msz[N],vis[N];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[x]<msz[RT]) RT=x;
}
int sta[N],top,Lv[N],Rv[N],dep[N];
void dfs(int x,int fa,int R,int lv,int rv) {
sta[++top]=x;
dep[x]=R; Lv[x]=lv; Rv[x]=rv;
if(lv%p==0) ans++;
if(rv%p==0) ans++;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,R+1,(pr[R]*val[i]+lv)%p,((LL)rv*10+val[i])%p);
}
void exgcd(LL a,LL b,LL &d,LL &x,LL &y) {
if(!b) { d=a; x=1; y=0; return; }
exgcd(b,a%b,d,y,x); y-=a/b*x;
}
LL get_inv(int a,int p) {
LL d,x,y; exgcd(a,p,d,x,y);
return (x%p+p)%p;
}
map<int,int>mp;
void calc(int l,int r,int f) {
For(i,l,r) {
int x=sta[i],v=((LL)p-Rv[x])%p*prinv[dep[x]]%p;
ans+=f*mp[v]; mp[Lv[x]]++;
}
For(i,l,r) mp[Lv[sta[i]]]--;
Rep(i,r,l) {
int x=sta[i],v=((LL)p-Rv[x])%p*prinv[dep[x]]%p;
ans+=f*mp[v]; mp[Lv[x]]++;
}
For(i,l,r) mp[Lv[sta[i]]]--;
}
void solve(int x,int tot) {
vis[x]=1;
int szx=sz[x],prtop=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
dfs(to[i],x,1,val[i],val[i]);
calc(prtop+1,top,-1); prtop=top;
}
calc(1,top,1); top=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
get_root(to[i],x,lsz); solve(RT,lsz);
}
}
int main() {
//freopen("1.in","r",stdin);
//freopen("3730.out","w",stdout);
read(n); read(p);
pr[0]=1; prinv[0]=1;
prinv[1]=get_inv(10,p);
For(i,1,n) {
pr[i]=pr[i-1]*10%p;
if(i>1) prinv[i]=prinv[i-1]*prinv[1]%p;
}
For(i,2,n) {
int u,v,w;
read(u); read(v); read(w);
add(u+1,v+1,w%p);
}
get_root(1,0,n);
solve(RT,n);
printf("%I64d
",ans);
Formylove;
}
cf293 E. Close Vertices
.................................................................................1 차원 정렬 더 블 포인터 1 차원 트 리 배열 하면 됩 니 다.작은 틀
//Achen
#include
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=100007;
typedef long long LL;
typedef double db;
using namespace std;
int n,L,W;
LL ans;
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
void add(int u,int v,int w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}
int RT,sz[N],msz[N],vis[N];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[x]<msz[RT]) RT=x;
}
int sta[N],top,R[N],H[N];
void dfs(int x,int fa,int now,int cc) {
if(now>W||cc>L) return;
else ans++;
R[x]=cc;
H[x]=now;
sta[++top]=x;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,now+val[i],cc+1);
}
int cmp(const int &A,const int &B) { return H[A]<H[B]||(H[A]==H[B]&&R[A]<R[B]); }
int sum[N];
void add(int x,int v) {
for(int i=x;i<=L;i+=(i&(-i)))
sum[i]+=v;
}
int qry(int x) {
int rs=0;
for(int i=x;i;i-=(i&(-i)))
rs+=sum[i];
return rs;
}
int a[N],le;
void calc(int l,int r,int f) {
le=r-l+1; int np=0;
For(i,l,r) a[i-l+1]=sta[i];
sort(a+1,a+le+1,cmp);
For(i,1,le) {
while(np&&H[a[np]]+H[a[i]]>W) {
add(R[a[np]],-1); np--;
}
ans+=f*qry(L-R[a[i]]);
if(i<le&&H[a[i]]+H[a[i+1]]<=W) {
np++; add(R[a[i]],1);
}
}
For(i,1,np) add(R[a[i]],-1);
}
void solve(int x,int tot) {
vis[x]=1;
int szx=sz[x],prtop=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
dfs(to[i],x,val[i],1);
calc(prtop+1,top,-1); prtop=top;
}
calc(1,top,1); top=0;
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
get_root(to[i],x,lsz); solve(RT,lsz);
}
}
int main() {
//freopen("1.in","r",stdin);
//freopen("3730.out","w",stdout);
read(n); read(L); read(W);
For(i,2,n) {
int u,v;
read(u); read(v);
add(i,u,v);
}
get_root(1,0,n);
solve(RT,n);
printf("%I64d
",ans);
Formylove;
}
충격파
등...........................................................................포인터 동적 할당 메모리 트 리 배열 도 너무 좋 죠?근 데 조회 할 때 는 up 과 min 을 가 져 가 야 돼 요. 안 그러면 RE 잖 아 요!그리고 나 에 게 나무 에 있 는 모든 조상 과 내 가 그들 에 게 가 는 거 리 를 기록 하 세 요. 예전 에 나 는 lca 에 게 거 리 를 찾 아 달라 고 썼 습 니 다. 바보 가 아 닙 니까?각각 두 개의 나무 모양 의 배열 에 서브 트 리 안의 점 을 담 고 하 나 는 자신의 거 리 를 누 르 고 하 나 는 자신의 점 에 따라 아버지의 거 리 를 나눈다.
//Achen
#include
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=100007;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,val[N],tmp1[N*30],tmp2[N*30];
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N],nxt[N<<1],to[N<<1];
void add(int u,int v) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u;
}
int RT,sz[N],msz[N],vis[N];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[x]<msz[RT]) RT=x;
}
int *sum[2][N],*np1=tmp1+1,*np2=tmp2+1;
void ADD(int o,int id,int x,int v) {
for(int i=x;i<=sz[id];i+=(i&(-i)))
sum[o][id][i]+=v;
}
int qry(int o,int id,int x) {
int rs=0;
for(int i=min(sz[id],x);i;i-=(i&(-i)))
rs+=sum[o][id][i];
return rs;
}
vector<int>ds[N];
void dfs(int x,int fa,int R) {
ds[x].push_back(R);
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,R+1);
}
int p[N][20],dis[N][20];
void build(int x,int tot) {
vis[x]=1;
int szx=sz[x];
sz[x]=tot;
p[x][0]=x;
dfs(x,0,0);
sum[0][x]=np1; sum[1][x]=np2;
np1+=sz[x]+1; np2+=sz[x]+1;
int up=ds[x].size()-1;
For(i,0,18) {
if(i>1) p[x][i]=p[p[x][1]][i-1];
if(p[x][i]) dis[x][i]=ds[x][up--];
}
For(i,0,18) if(p[x][i]) {
ADD(0,p[x][i],dis[x][i]+1,val[x]);
if(p[x][i+1]) ADD(1,p[x][i],dis[x][i+1],val[x]);
}
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
RT=0; int lsz=sz[to[i]]>szx?tot-szx:sz[to[i]];
get_root(to[i],x,lsz); p[RT][1]=x; build(RT,lsz);
}
}
void change(int x,int y) {
For(i,0,18) if(p[x][i]) {
ADD(0,p[x][i],dis[x][i]+1,y-val[x]);
if(p[x][i+1]) ADD(1,p[x][i],dis[x][i+1],y-val[x]);
}
val[x]=y;
}
int lastans;
void Qry(int x,int k) {
int rs=0;
For(i,0,18) {
if(!p[x][i]) break;
if(k>=dis[x][i]) rs+=qry(0,p[x][i],k-dis[x][i]+1);
if(p[x][i+1]&&k>dis[x][i+1]) rs-=qry(1,p[x][i],k-dis[x][i+1]);
}
printf("%d
",rs); lastans=rs;
}
int main() {
//freopen("3730.in","r",stdin);
//freopen("3730.out","w",stdout);
read(n); read(m);
For(i,1,n) read(val[i]);
For(i,2,n) {
int u,v;
read(u); read(v);
add(u,v);
}
get_root(1,0,n);
build(1,n);
For(i,1,m) {
int op,x,y;
read(op); read(x); read(y);
x^=lastans; y^=lastans;
if(!op) Qry(x,y);
else change(x,y);
}
Formylove;
}
cf757 G. Can Bash Save the Day?
................................................................................................q 개 동작 이 있 습 니 다:
1 l r x: 문의 ∑ i = l r d i s t (p i, x) \ \ sum \ \ limits{i=l}^r dist(p_i,x) i=l∑rdist(pi,x) 2 x: s w a p ( p x , p x + 1 ) swap(p_x,p_{x+1}) swap(px,px+1)
n , q ≤ 2 × 1 0 5 n,q\le 2\times 10^5 n,q≤2×105, 강제 온라인.
강사 가 이것 은 지속 가능 한 나무 라 고 말 했 는데, 나 는 이것 이 set 물 을 건 널 수 있 지 않 겠 습 니까?그리고 즐겁게 때 리 고 즐겁게 T 를 했 어 요.각 점 은 set 로 관할 범 위 를 유지 하 는 점 이 a 의 순서 로 접두사 와 두 개의 log 이 고 70 여 개의 점 이 있 을 때 TLE 입 니 다.
//Achen
#include
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=2e5+7;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,a[N],p[N];
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
struct node {
int pos; LL sum[3];
friend bool operator <(const node&A,const node&B) {
return A.pos<B.pos;
}
};
set<node>rt[N];
int ecnt,fir[N],nxt[N<<1],to[N<<1],val[N<<1];
void add(int u,int v,int w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}
int RT,sz[N],msz[N],vis[N];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[RT]>msz[x]) RT=x;
}
vector<LL>ds[N];
int sta[N],top;
void dfs(int x,int fa,LL R) {
sta[++top]=x;
ds[x].push_back(R);
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,R+val[i]);
}
bool cmp(const int&A,const int&B) { return p[A]<p[B]; }
int f[N][20];
LL dis[N][20];
void build(int x,int tot) {
vis[x]=1;
top=0;
dfs(x,0,0);
sort(sta+1,sta+top+1,cmp);
LL s1=0,s2=0,s3=0;
For(i,1,top) {
int u=sta[i],up=ds[u].size()-1;
s1++; s2+=ds[u][up]; s3+=(up>0?ds[u][up-1]:0);
rt[x].insert((node){p[u],s1,s2,s3});
}
f[x][0]=x; int up=ds[x].size()-1;
For(i,0,18) {
if(i>1) f[x][i]=f[f[x][1]][i-1];
if(f[x][i]) dis[x][i]=ds[x][up--];
}
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
RT=0; int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
assert(lsz*2<=tot+5);
get_root(to[i],x,lsz);
f[RT][1]=x; build(RT,lsz);
}
}
#define IT set::iterator
LL lastans;
void qry(int ql,int qr,int x) {
LL rs=0;
For(i,0,18) if(f[x][i]) {
int y=f[x][i];
IT it=rt[y].lower_bound((node){ql,0});
if(it==rt[y].end()) continue;
if(it!=rt[y].begin()) {
--it; rs-=((*it).sum[1]+(*it).sum[0]*dis[x][i]);
if(f[x][i+1]) rs+=((*it).sum[2]+(*it).sum[0]*dis[x][i+1]);
}
it=rt[y].lower_bound((node){qr,0});
node tpp=*it;
if(it==rt[y].end()||(*it).pos>qr) {
if(it==rt[y].begin()) continue;
--it;
}
tpp=*it;
rs+=((*it).sum[1]+(*it).sum[0]*dis[x][i]);
if(f[x][i+1]) rs-=((*it).sum[2]+(*it).sum[0]*dis[x][i+1]);
}
printf("%lld
",rs); lastans=rs;
}
void change(int x) {
For(i,0,18) if(f[a[x]][i]) {
int u=f[a[x]][i];
IT it=rt[u].lower_bound((node){x});
node tp=*it;
rt[u].erase(it);
it=rt[u].lower_bound((node){x});
if(it!=rt[u].end()&&(*it).pos==x+1) {
node tp2=*it;
LL t1=tp.sum[1]-dis[a[x]][i]+tp2.sum[1]-tp.sum[1];
LL t2=tp.sum[2]-dis[a[x]][i+1]+tp2.sum[2]-tp.sum[2];
rt[u].insert((node){x,tp.sum[0],t1,t2});
}
else { tp.pos++; rt[u].insert(tp); }
}
For(i,0,18) if(f[a[x+1]][i]) {
int u=f[a[x+1]][i];
IT it=rt[u].lower_bound((node){x+1,0}),it2=it;
if(it2!=rt[u].begin()) it2--;
if((*it2).pos==x) break;
node t=*it; t.pos--;
rt[u].erase(it); rt[u].insert(t);
}
swap(a[x],a[x+1]);
p[a[x]]=x; p[a[x+1]]=x+1;
}
int main() {
//freopen("1.in","r",stdin);
//freopen("WA.out","w",stdout);
read(n); read(m);
For(i,1,n) read(a[i]),p[a[i]]=i;
For(i,2,n) {
int u,v,w;
read(u); read(v); read(w);
add(u,v,w);
}
RT=0; get_root(1,0,n);
build(RT,n);
For(i,1,m) {
int op,x,l,r;
read(op);
if(op==1) {
read(l); read(r); read(x);
l^=lastans%(1<<30); r^=lastans%(1<<30); x^=lastans%(1<<30);
qry(l,r,x);
}
else {
read(x);
x^=lastans%(1<<30);
change(x);
}
}
Formylove;
}
어 쩔 수 없어. 나 무 를 오래 갈 수 밖 에 없어...a 의 순서에 따라 지난 번 에 나 무 를 만 들 었 습 니 다. 각 점 은 현재 기여 한 점 수 를 유지 하고 아버지 와 의 거리 와 매번 체인 을 새로 만 듭 니 다.수정 은 x 라 는 나무 에 만 영향 을 주 고 앞 뒤의 나 무 는 변 하지 않 기 때문에 x - 1 을 바탕 으로 새로운 x 를 만 들 면 됩 니 다.그리고 지속 가능 해 야 하기 때문에 두 갈래 를 강제로 돌려 야 한다.밑 에서 위로 올 라 가 는 우수한 점 수 를 억지로 위 에서 아래로 나 누 는 추악 한 물건 으로 만 들 었 다.
//Achen
#include
#define For(i,a,b) for(register int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(register int i=(a);i>=(b);i--)
#define Formylove return 0
const int N=2e5+7;
typedef long long LL;
typedef double db;
using namespace std;
int n,m,a[N];
template<typename T> void read(T &x) {
char ch=getchar(); T f=1; x=0;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=-1,ch=getchar();
for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}
int ecnt,fir[N<<1],nxt[N<<2],to[N<<2],val[N<<2];
void add(int u,int v,int w) {
nxt[++ecnt]=fir[u]; fir[u]=ecnt; to[ecnt]=v; val[ecnt]=w;
nxt[++ecnt]=fir[v]; fir[v]=ecnt; to[ecnt]=u; val[ecnt]=w;
}
int top,cnt,bvs[N<<1];
#define pr pair
#define MP make_pair
#define se second
#define fi first
vector<pr>son[N],son2[N<<1];
void prebuild(int x,int fa) {
int up=son[x].size();
For(i,0,up-1) if(son[x][i].fi!=fa) {
son2[x].push_back(son[x][i]);
prebuild(son[x][i].fi,x);
}
}
void rebuild(int x) {
int up=son2[x].size();
bvs[x]=1;
if(up<=2) {
For(i,0,up-1) add(x,son2[x][i].fi,son2[x][i].se);
}
else if(up==3) {
son2[++cnt].push_back(son2[x][0]);
son2[cnt].push_back(son2[x][1]);
add(x,cnt,0); add(x,son2[x][2].fi,son2[x][2].se);
}
else {
For(i,0,up-1) {
if(i&1) son2[cnt+1].push_back(son2[x][i]);
else son2[cnt+2].push_back(son2[x][i]);
}
add(x,++cnt,0); add(x,++cnt,0);
}
for(int i=fir[x];i;i=nxt[i]) if(!bvs[to[i]])
rebuild(to[i]);
}
int RT,sz[N<<1],msz[N<<1],vis[N<<1];
void get_root(int x,int fa,int tot) {
sz[x]=msz[x]=1;
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]]) {
get_root(to[i],x,tot);
sz[x]+=sz[to[i]];
msz[x]=max(msz[x],sz[to[i]]);
}
msz[x]=max(msz[x],tot-sz[x]);
if(!RT||msz[RT]>msz[x]) RT=x;
}
vector<LL>ds[N<<1];
void dfs(int x,int fa,LL R) {
ds[x].push_back(R);
for(int i=fir[x];i;i=nxt[i]) if(to[i]!=fa&&!vis[to[i]])
dfs(to[i],x,R+val[i]);
}
int totnd,rt[N],tr[N*60],ch[N*60][3];
LL sum[N*60][3];
LL dis[N<<1][20];
int dfk,dfn[N<<1],low[N<<1],tR[N<<1];
int in(int a,int b) { return dfn[a]>=dfn[b]&&dfn[a]<=low[b]; }
void build(int x,int tot) {
tr[x]=x;
vis[x]=1;
dfs(x,0,0);
dfn[x]=low[x]=++dfk;
int up=ds[x].size()-1,xson=0;
For(i,0,18) if(up>=0)
dis[x][i]=ds[x][up--];
for(int i=fir[x];i;i=nxt[i]) if(!vis[to[i]]) {
int lsz=sz[to[i]]>sz[x]?tot-sz[x]:sz[to[i]];
RT=0; get_root(to[i],x,lsz);
ch[x][xson++]=RT; tR[RT]=tR[x]+1;
build(RT,lsz); low[x]=max(low[x],low[RT]);
}
}
void upd(int &x,int last,int R,int nd) {
x=++totnd;
tr[x]=tr[last];
For(i,0,2) ch[x][i]=ch[last][i],sum[x][i]=sum[last][i];
sum[x][0]++;
sum[x][1]+=dis[nd][tR[nd]-R];
if(R) sum[x][2]+=dis[nd][tR[nd]-R+1];
if(tr[x]==nd) return;
For(i,0,2) if(ch[x][i]&&in(nd,tr[ch[x][i]]))
upd(ch[x][i],ch[last][i],R+1,nd);
}
LL Qrs;
void preQ() { Qrs=0; }
void qry(int x,int R,int nd) {
Qrs+=(sum[x][1]+sum[x][0]*dis[nd][tR[nd]-R]);
if(R) Qrs-=(sum[x][2]+sum[x][0]*dis[nd][tR[nd]-R+1]);
if(tr[x]==nd) return;
For(i,0,2) if(ch[x][i]&&in(nd,tr[ch[x][i]]))
qry(ch[x][i],R+1,nd);
}
LL lastans;
void Qry(int ql,int qr,int x) {
LL rs=0;
preQ(); qry(rt[qr],0,x); rs+=Qrs;
preQ(); if(ql-1) qry(rt[ql-1],0,x); rs-=Qrs;
printf("%I64d
",rs); lastans=rs%(1<<30);
}
int main() {
//freopen("std.in","r",stdin);
//freopen("WA.out","w",stdout);
read(n); read(m);
For(i,1,n) read(a[i]);
For(i,2,n) {
int u,v,w;
read(u); read(v); read(w);
son[u].push_back(MP(v,w));
son[v].push_back(MP(u,w));
}
cnt=n;
prebuild(1,0); rebuild(1);
RT=0; get_root(1,0,cnt);
rt[0]=RT; build(RT,cnt);
totnd=cnt;
For(i,1,n)
upd(rt[i],rt[i-1],0,a[i]);
int qc=0;
For(i,1,m) {
int op,x,l,r;
read(op);
if(op==1) {
read(l); read(r); read(x);
l^=lastans; r^=lastans; x^=lastans;
Qry(l,r,x);
}
else {
read(x); x^=lastans;
upd(rt[x],rt[x-1],0,a[x+1]);
swap(a[x],a[x+1]);
}
}
Formylove;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.