Codeforces Round #254 (Div. 2)(并查集,线段树)

来源:互联网 发布:奥一网 网络问政 编辑:程序博客网 时间:2024/05/22 15:58
B. DZY Loves Chemistry
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves chemistry, and he enjoys mixing chemicals.

DZY has n chemicals, and m pairs of them will react. He wants to pour these chemicals into a test tube, and he needs to pour them in one by one, in any order.

Let's consider the danger of a test tube. Danger of an empty test tube is 1. And every time when DZY pours a chemical, if there are already one or more chemicals in the test tube that can react with it, the danger of the test tube will be multiplied by2. Otherwise the danger remains as it is.

Find the maximum possible danger after pouring all the chemicals one by one in optimal order.

Input

The first line contains two space-separated integers n andm.

Each of the next m lines contains two space-separated integersxi andyi(1 ≤ xi < yi ≤ n). These integers mean that the chemicalxi will react with the chemicalyi. Each pair of chemicals will appear at most once in the input.

Consider all the chemicals numbered from 1 to n in some order.

Output

Print a single integer — the maximum possible danger.

Sample test(s)
Input
1 0
Output
1
Input
2 11 2
Output
2
Input
3 21 22 3
Output
4
Note

In the first sample, there's only one way to pour, and the danger won't increase.

In the second sample, no matter we pour the 1st chemical first, or pour the2nd chemical first, the answer is always2.

In the third sample, there are four ways to achieve the maximum possible danger: 2-1-3, 2-3-1, 1-2-3 and 3-2-1 (that is the numbers of the chemicals in order of pouring).


思路:同一集合中的元素最多肯定是反应n-1次,所以用并查集统计这个集合中的元素有多少个

#include<iostream>#include<queue>#include<cstring>#include<cstdio>#include<cmath>#include<set>#include<map>#include<vector>#include<stack>#include<algorithm>const int MAXN=60;typedef long long LL;using namespace std;int N,M,p[MAXN],cnt[MAXN];int find(int x){    return x==p[x]?x:p[x]=find(p[x]);}int main(){    scanf("%d%d",&N,&M);    for(int i=1; i<=N; i++)    {        cnt[i]=1;        p[i]=i;    }    int u,v;    for(int i=0; i<M; i++)    {        scanf("%d%d",&u,&v);        int x=find(u),y=find(v);        if(x!=y)        {            p[x]=y;            cnt[y]+=cnt[x];        }    }    LL ans=1;    for(int i=1; i<=N; i++) if(find(i)==i) ans*=(1LL<<(cnt[i]-1));    cout<<ans<<endl;    return 0;}

E. DZY Loves Colors
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

DZY loves colors, and he enjoys painting.

On a colorful day, DZY gets a colorful ribbon, which consists of n units (they are numbered from 1 ton from left to right). The color of thei-th unit of the ribbon is i at first. It is colorful enough, but we still consider that the colorfulness of each unit is0 at first.

DZY loves painting, we know. He takes up a paintbrush with color x and uses it to draw a line on the ribbon. In such a case some contiguous units are painted. Imagine that the color of uniti currently isy. When it is painted by this paintbrush, the color of the unit becomesx, and the colorfulness of the unit increases by|x - y|.

DZY wants to perform m operations, each operation can be one of the following:

  1. Paint all the units with numbers between l andr (both inclusive) with colorx.
  2. Ask the sum of colorfulness of the units between l andr (both inclusive).

Can you help DZY?

Input

The first line contains two space-separated integers n, m (1 ≤ n, m ≤ 105).

Each of the next m lines begins with a integertype (1 ≤ type ≤ 2), which represents the type of this operation.

If type = 1, there will be 3 more integers l, r, x (1 ≤ l ≤ r ≤ n; 1 ≤ x ≤ 108) in this line, describing an operation1.

If type = 2, there will be 2 more integers l, r (1 ≤ l ≤ r ≤ n) in this line, describing an operation2.

Output

For each operation 2, print a line containing the answer — sum of colorfulness.

Sample test(s)
Input
3 31 1 2 41 2 3 52 1 3
Output
8
Input
3 41 1 3 42 1 12 2 22 3 3
Output
321
Input
10 61 1 5 31 2 7 91 10 10 111 3 8 121 1 10 32 1 10
Output
129
Note

In the first sample, the color of each unit is initially [1, 2, 3], and the colorfulness is [0, 0, 0].

After the first operation, colors become [4, 4, 3], colorfulness become[3, 2, 0].

After the second operation, colors become [4, 5, 5], colorfulness become[3, 3, 2].

So the answer to the only operation of type 2 is8.


线段树,比赛的时候敲了一个多小时,最后发现自己看错题了。。。

赛后看别人的代码,果然是大神。

本来想的是维护区间上的和没然后set标记后,可以直接相减得到该区间上的变化量,后来发现是错的,这样相当于没有取绝对值。从别人的代码中得到启发,果然很神奇。需要有一个sum维护区间上变化量的总值,val维护前面的所有操作改变量的总和,setv表示当前图的颜色。当前这一段如果没有被吐过,则一定会更新到底。其他的详见代码。

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=100010;typedef long long LL;int n,m;struct IntervalTree{    LL sum[maxn<<3],setv[maxn<<3],val[maxn<<3];    void pushup(int o)    {        sum[o]=sum[o<<1]+sum[o<<1|1];        if(setv[o<<1]==setv[o<<1|1])setv[o]=setv[o<<1];//如果左右孩子的setv一样表示他们的颜色是一样的那么父亲节点的setv值就可以更新        else setv[o]=0;    }    void build(int o,int l,int r)    {        sum[o]=val[o]=setv[o]=0;        if(l==r)        {            setv[o]=l;            return ;        }        int mid=(l+r)/2;        build(o<<1,l,mid);        build(o<<1|1,mid+1,r);        pushup(o);    }    void pushdown(int o,int l,int r)    {        if(val[o])        {            int mid=(l+r)>>1;            sum[o<<1]+=val[o]*(mid-l+1);//这里只能是用父节点的val来更新sum,不能用val[o<<1]*(r-l+1),因为以前的sum个能是左右孩子来更新的            sum[o<<1|1]+=val[o]*(r-mid);            val[o<<1]+=val[o];            val[o<<1|1]+=val[o];            setv[o<<1]=setv[o<<1|1]=setv[o];            val[o]=setv[o]=0;        }    }    void update(int o,int l,int r,int q1,int q2,LL x)    {        if(q1<=l&&r<=q2)        {            if(setv[o])//setv不等于0说明这个区间以前被涂过色,可以直接用(r-l+1)*abs(setv[o]-x)算出这次的变化,如果不是0,则因为绝对值的原因不能直接这样算,需要从她的孩子节点来维护她            {                sum[o]+=(r-l+1)*abs(setv[o]-x);                val[o]+=abs(setv[o]-x);                setv[o]=x;                return;            }        }        int mid=(l+r)>>1;        pushdown(o,l,r);//往下推的是val这个差值的总和和setv        if(q1<=mid)update(o<<1,l,mid,q1,q2,x);        if(q2>mid)update(o<<1|1,mid+1,r,q1,q2,x);        pushup(o);//根据孩子的值维护父亲    }    LL query(int o,int l,int r,int q1,int q2)    {        int mid=((l+r)/2);        if(q1<=l&&r<=q2)            return sum[o];        pushdown(o,l,r);        LL x=0,y=0;        if(q1<=mid)x=query(o<<1,l,mid,q1,q2);        if(q2>mid)y=query(o<<1|1,mid+1,r,q1,q2);        pushup(o);        return x+y;    }}tree;int main(){    freopen("in.txt","r",stdin);    int op,a,b,v;    scanf("%d%d",&n,&m);    tree.build(1,1,n);    while(m--)    {        scanf("%d%d%d",&op,&a,&b);        if(op==1)        {            scanf("%d",&v);            tree.update(1,1,n,a,b,v);        }        else cout<<tree.query(1,1,n,a,b)<<endl;    }    return 0;}




0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 香港过境想去澳门怎么办 加拿大博士资格考试没通过怎么办 外国人没有学历怎么办工作签证 澳洲语言班挂了怎么办 英国学位翻译成文学硕士怎么办 没考上好的高中怎么办 毕业证12月发放申请英国怎么办 高二迷茫成绩差怎么办 高二期末考的差怎么办 法国留学签证办不下来怎么办 澳洲留学挂科签证续签怎么办 澳洲旅游签证被拒了怎么办 学校六级不让刷分怎么办 英国留学生怎么办申根签证 挂科太多拿不到学位证怎么办 ucl语言班没过怎么办 西澳大学工程挂科怎么办 澳洲语言班没过怎么办2018 杨浦区对口公立小学太差怎么办 公立小学太差了怎么办 澳大利亚出国留学怎么办-语言课程 学校不给释放信怎么办 重修费交不起钱怎么办 不想用家里的钱怎么办 三本学费太贵怎么办 从日本往中国汇款怎么办 学费钱大一没交怎么办 初中孩子和同学相处不好怎么办 使用假护照出国被发现怎么办 酒店忘记退房了怎么办 语言课申请不上怎么办 学会计的应届生想转行怎么办 上班熬不下去了怎么办 墨大选修挂科怎么办 日本签证年收入没有10w怎么办 做生意的办房贷没有薪资流水怎么办 澳洲医保卡丢了怎么办 澳洲爱他美上火怎么办 学信网学籍在籍没交学费怎么办 宝宝从床上摔下来怎么办 狗没打针被咬了怎么办