NOIP的东西回成都再说吧。。。
这题暴力。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxv 100500 #define maxe 200500 using namespace std; int n,q,x,y,z,val[maxv],anc[maxv][20],dis[maxv],g[maxv],nume=0; int s[maxv],top=0; struct edge { int v,nxt; }e[maxe]; void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } int read() { char ch;int data=0; while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { data=data*10+ch-'0'; ch=getchar(); } return data; } void dfs(int x,int fath) { for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (v!=fath) { anc[v][0]=x;dis[v]=dis[x]+1; dfs(v,x); } } } void get_table() { for (int e=1;e<=19;e++) for (int i=1;i<=n;i++) anc[i][e]=anc[anc[i][e-1]][e-1]; } int lca(int x,int y) { if (dis[x]<dis[y]) swap(x,y); for (int e=19;e>=0;e--) { if ((dis[anc[x][e]]>=dis[y]) && (anc[x][e])) x=anc[x][e]; } if (x==y) return x; for (int e=19;e>=0;e--) { if (anc[x][e]!=anc[y][e]) { x=anc[x][e]; y=anc[y][e]; } } return anc[x][0]; } void get_push(int t) { top=0; while (x!=t) {s[++top]=val[x];x=anc[x][0];} while (y!=t) {s[++top]=val[y];y=anc[y][0];} s[++top]=val[t]; } void ask() { int t=lca(x,y),tot=dis[x]+dis[y]-dis[t]-dis[anc[t][0]]; if (tot>50) {printf("Y\n");return;} get_push(t); sort(s+1,s+top+1); int flag=1; for (int i=1;i<=top-2;i++) { if ((long long)s[i]+(long long)s[i+1]>(long long)s[i+2]) flag=0; } if (flag) printf("N\n"); else printf("Y\n"); } int main() { n=read();q=read(); for (int i=1;i<=n;i++) val[i]=read(); for (int i=1;i<=n-1;i++) { x=read();y=read(); addedge(x,y);addedge(y,x); } dis[1]=1;dfs(1,0);get_table(); for (int i=1;i<=q;i++) { z=read();x=read();y=read(); if (z) val[x]=y; else ask(); } return 0; }