您的位置:首页 > 产品设计 > UI/UE

The 10th UESTC Programming Contest Final 总结

2013-04-30 23:37 483 查看
E.Electric System Restore

  如果没有k个城市可以独立供电,我们就直接找到x和y的中位数,然后计算距离和就可以了,现在要去掉k个城市,很明显,中位数位置的偏移不超过k/2+1,这样,我们分别枚举x和y在[n/2-k/2-1,n/2+k/2+1]的位置就可以找到最优情况了.

UESTC 1653

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 50010
#define lson l,m,root<<1
#define rson m+1,r,root<<1|1
#define INF 0x3f3f3f3f3f3f3f3fll

vector<int>road[maxn];
bool mark[maxn];
int l[maxn],r[maxn],dep[maxn],num,addcnt[maxn<<2];//sum 多加的权值 cnt加过的次数
long long depsum[maxn],sum[maxn<<2],addsum[maxn<<2];

void pushup(int root){
sum[root]=sum[root<<1]+sum[root<<1|1];
}

void dfs(int pos,int deep){
l[pos]=num++;
dep[l[pos]]=deep;
int size=road[pos].size();
for(int i=0;i<size;i++)
if(!mark[road[pos][i]]){
mark[road[pos][i]]=1;
dfs(road[pos][i],deep+1);
}
r[pos]=num-1;
}

void pushdown(int root,int l,int r){
int mid=(l+r)>>1;
int ls=(root<<1);
int rs=(root<<1|1);
if(addsum[root]!=INF){
if(addsum[ls]==INF) addsum[ls]=0;
if(addsum[rs]==INF) addsum[rs]=0;
addsum[ls]+=addsum[root];
addsum[rs]+=addsum[root];
addcnt[ls]+=addcnt[root];
addcnt[rs]+=addcnt[root];
sum[ls]+=addcnt[root]*(depsum[mid]-depsum[l-1])-addsum[root]*(mid-l+1);
sum[rs]+=addcnt[root]*(depsum[r]-depsum[mid])-addsum[root]*(r-mid);
addcnt[root]=0;
addsum[root]=INF;
}
}

void update(int l,int r,int root,int s,int e,int add){
if(s<=l&&e>=r){
sum[root]+=depsum[r]-depsum[l-1]-add*(r-l+1);
if(addsum[root]==INF)
addsum[root]=0;
addsum[root]+=add;
addcnt[root]++;
return;
}
int m=(l+r)>>1;
pushdown(root,l,r);
if(m>=s)
update(lson,s,e,add);
if(m<e)
update(rson,s,e,add);
pushup(root);
}

long long query(int l,int r,int root,int s,int e){
if(s<=l&&e>=r) return sum[root];
double ret=0; int m=(l+r)>>1;
pushdown(root,l,r);
if(m>=s) ret+=query(lson,s,e);
if(m<e)    ret+=query(rson,s,e);
pushup(root);
return ret;
}

int main(){
int T,temp,i,n,p,a,b,cases=0;
char ch[20];
scanf("%d",&T);
while(T--){
cases++;
scanf("%d%d",&n,&p);
memset(mark,0,sizeof(mark));
memset(sum,0,sizeof(sum));
memset(addsum,0x3f,sizeof(addsum));
memset(addcnt,0,sizeof(addcnt));
for(i=0;i<=n;i++)
road[i].clear();
for(i=2;i<=n;i++){
scanf("%d",&temp);
road[i].push_back(temp);
road[temp].push_back(i);
}
num=1; mark[1]=1;
dfs(1,1); depsum[0]=0;
for(i=1;i<=n;i++)
depsum[i]=depsum[i-1]+dep[i];
printf("Case #%d:\n",cases);
while(p--){
scanf("%s",ch);
if(ch[0]=='A'){
scanf("%d%d",&a,&b);
update(1,n,1,l[a],r[a],dep[l[a]]-b);
}
else{
scanf("%d",&a);
printf("%lld\n",query(1,n,1,l[a],r[a]));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: