COGS 1612. 大话西游 (线段树)
来源:互联网 发布:金融大数据 pdf 编辑:程序博客网 时间:2024/05/16 12:00
【题目描述】代码
“大话西游”是一个在中国非常流行的在线游戏,由NIE公司开发和维护。这个游戏来源于著名的小说《西游记》和周星弛的电影,游戏的背景故事充满奇幻色彩,引人入胜。
游戏里面有很多片区域,不同的区域由不同的统治者管辖,其中有一个地方名叫“树国”,由一个妖怪控制着。这里有N个城堡,每个城堡都有其重要程度值(一个正整数,不超过10^8),这些城堡被N-1条双向道路所连接,任意两个城堡均可互达,城堡的重要程度值是可变的。现在,妖怪想知道如果破坏其中的一条道路会发生什么。本题中,你总共需要处理Q条指令,每一个都具有下面所述的格式:
(1)CHANGE
i w
本指令的含义为:将第i个城堡的重要程度值变为w(1<=w<=10^8)
(2)QUERY
j
本指令的含义为:输出min1*max1+min2*max2的值,详细如下:
第j条道路可以把“树国”分成两个连通块,分别称为part1和part2,其中
min1为part1中的最小重要程度值;
max1为part1中的最大重要程度值;
min2为part2中的最小重要程度值;
max2为part2中的最大重要程度值。
【输入格式】
第一行有两个整数N(2<=N<=100000)和Q(1<=Q<=100000),分别表示城堡的个数及指令的数目。
接下来的一行有N个整数(正整数,不超过10^8),表示起初每一个城堡的重要程度值(城堡的编号为1~N)。
接下来有N-1行,每行有两个整数u,v,表示在城堡u和城堡v之间有一条无向边相连,(边的编号依次为1~N-1)。
接下来有Q行,每行有一个指令,格式如下所述。
【输出格式】
对于每个"QUERY"指令,在单独一行输出结果。
【样例输入】
5 31 2 3 4 51 22 33 44 5QUERY 1CHANGE 1 10QUERY 1
【样例输出】
11110
暴力只有60 分(不要问我怎么知道,因为我试过了)
那正解就是线段树维护dfs序
因为dfs序是有序的 深搜嘛。。
然后操作就是 单点修改+区间求最值
至于断边的时候自己画画吧
1 #include <ctype.h> 2 #include <cstdio> 3 4 const int MAXN=200010; 5 6 int n,q,num; 7 8 int a[MAXN],siz[MAXN],id[MAXN],dfn[MAXN],pre[MAXN]; 9 10 struct node { 11 int to; 12 int th; 13 int next; 14 }; 15 node e[MAXN]; 16 17 int head[MAXN],tot=1; 18 19 struct data { 20 int l,r; 21 int mn,mx; 22 }; 23 data t[MAXN<<2]; 24 25 char s[10]; 26 27 void read(int&x) { 28 register char c=getchar(); 29 for(x=0;!isdigit(c);c=getchar()); 30 for(;isdigit(c);x=x*10+c-48,c=getchar()); 31 } 32 33 void add(int x,int y,int now) { 34 e[++tot].to=y; 35 e[tot].th=now; 36 e[tot].next=head[x]; 37 head[x]=tot; 38 } 39 40 int min(int a,int b) {return a<b?a:b;} 41 42 int max(int a,int b) {return a<b?b:a;} 43 44 void dfs(int now,int fa) { 45 siz[now]=1;dfn[now]=++num;id[num]=now; 46 for(int i=head[now];i;i=e[i].next) { 47 int to=e[i].to; 48 if(to==fa) continue; 49 pre[e[i].th]=to; 50 dfs(to,now); 51 siz[now]+=siz[to]; 52 } 53 } 54 55 void build_tree(int now,int l,int r) { 56 t[now].l=l;t[now].r=r; 57 if(l==r) { 58 t[now].mn=t[now].mx=a[id[l]]; 59 return; 60 } 61 int mid=(r+l)>>1; 62 build_tree(now<<1,l,mid); 63 build_tree(now<<1|1,mid+1,r); 64 t[now].mn=min(t[now<<1].mn,t[now<<1|1].mn); 65 t[now].mx=max(t[now<<1].mx,t[now<<1|1].mx); 66 } 67 68 void modify(int now,int x,int val) { 69 if(t[now].l==t[now].r) { 70 t[now].mn=t[now].mx=val; 71 return; 72 } 73 int mid=(t[now].l+t[now].r)>>1; 74 if(x<=mid) modify(now<<1,x,val); 75 if(x>mid) modify(now<<1|1,x,val); 76 t[now].mn=min(t[now<<1].mn,t[now<<1|1].mn); 77 t[now].mx=max(t[now<<1].mx,t[now<<1|1].mx); 78 } 79 80 int query_mn(int now,int l,int r) { 81 if(l<=t[now].l&&r>=t[now].r) return t[now].mn; 82 int mn1=1e9,mn2=1e9; 83 int mid=(t[now].l+t[now].r)>>1; 84 if(l<=mid) mn1=min(mn1,query_mn(now<<1,l,r)); 85 if(r>mid) mn2=min(mn2,query_mn(now<<1|1,l,r)); 86 return mn1<mn2?mn1:mn2; 87 } 88 89 int query_mx(int now,int l,int r) { 90 if(l<=t[now].l&&r>=t[now].r) return t[now].mx; 91 int mx1=-1,mx2=-1; 92 int mid=(t[now].l+t[now].r)>>1; 93 if(l<=mid) mx1=max(mx1,query_mx(now<<1,l,r)); 94 if(r>mid) mx2=max(mx2,query_mx(now<<1|1,l,r)); 95 return mx1<mx2?mx2:mx1; 96 } 97 98 int hh() { 99 freopen("westward.in","r",stdin);100 // freopen("westward.out","w",stdout);101 int x,y;102 read(n);read(q);103 for(int i=1;i<=n;++i) read(a[i]);104 for(int i=1;i<n;++i) {105 read(x);read(y);106 add(x,y,i);add(y,x,i);107 }108 dfs(1,0);109 for(int i=1;i<=n;++i) printf("%d ",dfn[i]);110 printf("\n"); 111 build_tree(1,1,n);112 #define LL long long113 for(int i=1;i<=q;++i) {114 scanf("%s",s);115 if(s[0]=='C') {116 read(x);read(y);117 modify(1,dfn[x],y);118 }119 else {120 read(x);121 int l=dfn[pre[x]],r=l+siz[pre[x]]-1;122 int min1=query_mn(1,l,r),max1=query_mx(1,l,r);123 int min2,max2;124 if(l!=1) min2=query_mn(1,1,l-1),max2=query_mx(1,1,l-1);125 if(r!=n) min2=min(min2,(query_mn(1,r+1,n))),max2=max(max2,query_mx(1,r+1,n));126 LL ans=(LL)min1*(LL)max1+(LL)min2*(LL)max2;127 printf("%lld\n",ans);128 }129 }130 return 0;131 }132 133 int sb=hh();134 int main() {;}
阅读全文
0 0
- COGS 1612. 大话西游 (线段树)
- 【线段树】COGS 1427. zwei
- cogs 859 数列【线段树】
- COGS 775. 山海经 【线段树】
- 【COGS】256 [POI2001] 金矿 线段树
- 【COGS】1272 [AHOI2009] 行星序列 线段树
- 线段树模板 cogs数列操作c
- COGS 577 蝗灾 线段树+CDQ分治
- 【COGS】950 切割矩形 线段树&树状数组
- 【线段树】【NOI 1999】【cogs 284】内存分配
- COGS-2275 [HEOI 2016] seq(树状数组+线段树)
- 《大话西游》
- 大话西游
- 大话西游
- 大话西游
- 大话西游
- 大话西游
- 大话西游
- [SDOI2009] 晨跑 (费用流) ---链表 VS Vector
- 14. [网络流24题] 搭配飞行员
- [网络流24题] 最小路径覆盖问题
- [网络流24题]魔术球问题
- java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
- COGS 1612. 大话西游 (线段树)
- [USACO Open07] 保护花朵 --贪心
- COGS 运输问题4 (费用流)
- 1006 最长公共子序列Lcs
- 博弈论 三大游戏
- [USACO Mar07] 月度花费
- P1901 发射站 单调栈
- 洛谷 P1823 音乐会的等待
- [JSOI2008]最大数 --线段树