博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NBOJv2 1034 Salary Inequity(DFS序+线段树区间更新区间(最值)查询)
阅读量:4597 次
发布时间:2019-06-09

本文共 7431 字,大约阅读时间需要 24 分钟。

 

Problem 1034: Salary Inequity

 

Time Limits:  10000 MS   Memory Limits:  200000 KB

64-bit interger IO format:  %lld   Java class name:  Main

Description

There is a large company of N employees. With the exception of one employee, everyone has a direct supervisor. The employee with no direct supervisor is indirectly a supervisor of all other employees in the company. We say that employee X is a subordinate of employee Y if either Y is the direct supervisor of X, or the direct supervisor of X is a subordinate of Y .

One day, the HR department decides that it wants to investigate how much inequity there is in the company with respect to salaries. For a given employee, the inequity of the employee is the difference between the minimum salary of that employee and all his/her subordinates and the maximum salary of that employee and all his/her subordinates.

HR wants to be able to compute the inequity for any employee quickly. However, this is complicated by the fact that an employee will sometimes give himself/herself, along with all his/her subordinates, a raise. Can you help? 

Input

The first line of your input file contains a number T representing the number of companies you will be analyzing for inequity. T will be at most 20.

For each company, there will be a line containing an integer N, representing the number of employees at the company. Each employee is assigned an ID which is a unique integer from 1 to N. The next line will contain N − 1 integers. The Kth integer in that line is the ID of the direct supervisor of employee (K + 1). The next line will contain N integers, the Kth integer in this line being the salary of employee K. The next line contains an integer Q, the number of events that you will need to process. There are two types of events to process - raises and inequity queries. In the event of a raise, the line will start with the letter R followed by the ID of the employee and an integer representing the increase in salary for that employee and all his/her subordinates. In the event of an inequity query, the line will start with the letter Q followed by the ID of the employee for whom inequity needs to be determined.

2 <= N <= 1,000,000

1 <= Q <= 10,000
For every employee K, the ID of his/her supervisor will be less than K. Initial salaries will

range from 1 to 1,000. No raise will exceed 1,000.

Output

For each inequity query, print the inequity of the employee on its own line. 

Sample Input

151 1 2 210 6 8 4 5 7Q 2Q 3R 4 2Q 2Q 1R 2 4Q 1

Output for Sample Input

20152

 

 

线段树是对于连续的区间操作,但是如果是一棵树,显然是仅符合线段树思想但并不连续,DFS标号构造一个序列,然后再用线段树处理……好题……,输入外挂优化后200MS+,一开始pushdown时左右子树的add忘记加了WA几次…

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x3f3f3f3f#define MM(x,y) memset(x,y,sizeof(x))#define LC(x) (x<<1)#define RC(x) ((x<<1)+1)#define MID(x,y) ((x+y)>>1)typedef pair
pii;typedef long long LL;const double PI=acos(-1.0);const int N=1000010;int total,in[N],OUT[N];int arr[N];int n;int ref[N];int head[N],cnt;struct info{ int to; int pre;}E[N<<1];struct seg{ int l,mid,r; int maxm,minm,add;};seg T[N<<2];void add(int s,int t){ E[cnt].to=t; E[cnt].pre=head[s]; head[s]=cnt++;}void dfs(int now,int fa){ in[now]=++total; ref[total]=now; for (int i=head[now]; ~i; i=E[i].pre) { int v=E[i].to; if(v!=fa) dfs(v,now); } OUT[now]=total;}void init(){ total=0; MM(in,0); MM(OUT,0); MM(arr,0); MM(ref,0); MM(head,-1); cnt=0;}void pushup(int k){ T[k].maxm=max(T[LC(k)].maxm,T[RC(k)].maxm); T[k].minm=min(T[LC(k)].minm,T[RC(k)].minm);}void pushdown(int k){ if(T[k].add) { T[LC(k)].add+=T[k].add; T[RC(k)].add+=T[k].add; T[LC(k)].maxm+=T[k].add; T[RC(k)].maxm+=T[k].add; T[LC(k)].minm+=T[k].add; T[RC(k)].minm+=T[k].add; T[k].add=0; } }void build(int k,int l,int r){ T[k].l=l; T[k].r=r; T[k].mid=MID(l,r); T[k].add=T[k].maxm=T[k].minm=0; if(l==r) { T[k].maxm=T[k].minm=arr[ref[l]];//初值的处理 return ; } build(LC(k),l,T[k].mid); build(RC(k),T[k].mid+1,r); pushup(k);}void update(int k,int l,int r,int val){ if(r
T[k].r) return ; if(l<=T[k].l&&r>=T[k].r) { T[k].add+=val; T[k].maxm+=val; T[k].minm+=val; } else { pushdown(k); update(LC(k),l,r,val); update(RC(k),l,r,val); pushup(k); }}int mmquery(int k,int l,int r){ if(l<=T[k].l&&r>=T[k].r) return T[k].maxm; pushdown(k); if(r<=T[k].mid) return mmquery(LC(k),l,r); else if(l>T[k].mid) return mmquery(RC(k),l,r); else return max(mmquery(LC(k),l,T[k].mid),mmquery(RC(k),T[k].mid+1,r));}int mnquery(int k,int l,int r){ if(l<=T[k].l&&r>=T[k].r) return T[k].minm; pushdown(k); if(r<=T[k].mid) return mnquery(LC(k),l,r); else if(l>T[k].mid) return mnquery(RC(k),l,r); else return min(mnquery(LC(k),l,T[k].mid),mnquery(RC(k),T[k].mid+1,r));}int Scan(){ int res=0,ch,flag=0; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; return flag?-res:res;}int main(void){ int tcase, i, x, q, val; char ops[3]; scanf("%d",&tcase); while (tcase--) { init(); scanf("%d",&n); for (i=1; i

另一种写法:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x3f3f3f3f#define MM(x,y) memset(x,y,sizeof(x))#define LC(x) (x<<1)#define RC(x) ((x<<1)+1)#define MID(x,y) ((x+y)>>1)typedef pair
pii;typedef long long LL;const double PI=acos(-1.0);const int N=1000010;struct info{ int to; int pre;}E[N];int head[N],cnt;int total,in[N],out[N];int arr[N];int n;struct seg{ int l,mid,r; int maxm,minm,add;};seg T[N<<2];void add(int s,int t){ E[cnt].to=t; E[cnt].pre=head[s]; head[s]=cnt++;}void dfs(int now,int fa){ in[now]=++total; for (int i=head[now]; ~i; i=E[i].pre) { int v=E[i].to; if(v!=fa) dfs(v,now); } out[now]=total;}void init(){ MM(head,-1); cnt=0; total=0; MM(in,0); MM(out,0); MM(arr,0);}void pushup(int k){ T[k].maxm=max(T[LC(k)].maxm,T[RC(k)].maxm); T[k].minm=min(T[LC(k)].minm,T[RC(k)].minm);}void pushdown(int k){ if(!T[k].add) return ; T[LC(k)].add+=T[k].add; T[RC(k)].add+=T[k].add; T[LC(k)].maxm+=T[k].add; T[RC(k)].maxm+=T[k].add; T[LC(k)].minm+=T[k].add; T[RC(k)].minm+=T[k].add; T[k].add=0;}void build(int k,int l,int r){ T[k].l=l; T[k].r=r; T[k].mid=MID(l,r); T[k].add=T[k].maxm=T[k].minm=0; if(l==r) return ; build(LC(k),l,T[k].mid); build(RC(k),T[k].mid+1,r);}void update(int k,int l,int r,int val){ if(r
T[k].r) return ; if(l<=T[k].l&&r>=T[k].r) { T[k].add+=val; T[k].maxm+=val; T[k].minm+=val; } else { pushdown(k); update(LC(k),l,r,val); update(RC(k),l,r,val); pushup(k); }}int mmquery(int k,int l,int r){ if(l<=T[k].l&&r>=T[k].r) return T[k].maxm; pushdown(k); if(r<=T[k].mid) return mmquery(LC(k),l,r); else if(l>T[k].mid) return mmquery(RC(k),l,r); else return max(mmquery(LC(k),l,T[k].mid),mmquery(RC(k),T[k].mid+1,r));}int mnquery(int k,int l,int r){ if(l<=T[k].l&&r>=T[k].r) return T[k].minm; pushdown(k); if(r<=T[k].mid) return mnquery(LC(k),l,r); else if(l>T[k].mid) return mnquery(RC(k),l,r); else return min(mnquery(LC(k),l,T[k].mid),mnquery(RC(k),T[k].mid+1,r));}int main(void){ int tcase, i, j, x, y, q, val; char ops[3]; scanf("%d",&tcase); while (tcase--) { init(); scanf("%d",&n); for (i=1; i

转载于:https://www.cnblogs.com/Blackops/p/5766285.html

你可能感兴趣的文章
MySql创建指定字符集的数据库
查看>>
bzoj 3172 AC自动机
查看>>
rabbitmq
查看>>
解决Latex中Itemize距离过大的问题
查看>>
1打印沙漏
查看>>
LeetCode | Rotate List
查看>>
CodeForces - 455D
查看>>
【转】Django模糊查询
查看>>
Bugtags 创业一年总结
查看>>
UML建模原理
查看>>
[BZOJ 1083] [SCOI2005] 繁忙的都市
查看>>
图解C#的值类型,引用类型,栈,堆,ref,out
查看>>
spring5.0版本-AOP-如何实现拦截器链式调用(责任链模式)
查看>>
dht11 temperature & humidity sensor v2
查看>>
selenium 启动 IE11
查看>>
习题6.6
查看>>
系统分析与设计第三次作业
查看>>
Redis——非阻塞IO和队列
查看>>
iPad最值得期待的切实改进构想
查看>>
(转载)ERROR :“dereferencing pointer to incomplete type”是什么错误?
查看>>