2016 Mulit-University Training Contest 8

来源:互联网 发布:dva防御矩阵用不了 编辑:程序博客网 时间:2024/05/19 06:38

HDU【5821】——Rikka with Sequence


Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has an array A with n numbers. Then he makes m operations on it.

There are three type of operations:

1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊A−−√[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

It is too difficult for Rikka. Can you help her?

Input

The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

It is guaranteed that 1<=A[i],x<=100000.

Output

For each operation of type 3, print a lines contains one number – the answer of the query.

Sample Input

1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5

Sample Output

5
6

Author

学军中学

题解:假设有4个红球,初始时从左到右标为1,2,3,4。那么肯定存在一种方案,使得最后结束时红球的顺序没有改变,也是1,2,3,4。 那么就可以把同色球都写成若干个不同色球了。所以现在共有n个颜色互异的球。按照最终情况标上1,2,。。,n的序号,那么贪心的来每次操作就是把一个区间排序就行了。orz

#include <bits/stdc++.h>using namespace std;const int Max  = 1100;int a[Max];int b[Max];queue<int>Q[Max];int main(){    int n,T,m,l,r;    scanf("%d",&T);    while(T--)    {        scanf("%d %d",&n,&m);        for(int i = 0; i<n; i++)        {            while(!Q[i].empty()) Q[i].pop();        }        for(int i = 0; i<n; i++) scanf("%d",&a[i]);        for(int i = 0; i<n; i++)        {            scanf("%d",&b[i]);            Q[b[i]].push(i);        }        bool flag = false;        for(int i = 0; i<n; i++)        {            if(flag) continue;            if(Q[a[i]].empty()) flag = true;            else            {                int  t= a[i];                a[i] = Q[a[i]].front();                Q[t].pop();            }        }        for(int i  = 0; i<m; i++)        {            scanf("%d %d",&l,&r);            if(flag) continue;            sort(a+l-1,a+r);        }        for(int i = 0; i<n; i++) if(a[i]!=i) flag = true;        if(flag) printf("No\n");        else printf("Yes\n");    }    return 0;}

HDU【5826】——physics


Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

There are n balls on a smooth horizontal straight track. The track can be considered to be a number line. The balls can be considered to be particles with the same mass.

At the beginning, ball i is at position Xi. It has an initial velocity of Vi and is moving in direction Di.(Di∈−1,1)
Given a constant C. At any moment, ball its acceleration Ai and velocity Vi have the same direction, and magically satisfy the equation that Ai * Vi = C.
As there are multiple balls, they may collide with each other during the moving. We suppose all collisions are perfectly elastic collisions.

There are multiple queries. Each query consists of two integers t and k. our task is to find out the k-small velocity of all the balls t seconds after the beginning.

  • Perfectly elastic collision : A perfectly elastic collision is defined as one in which there is no loss of kinetic energy in the collision.

Input

The first line contains an integer T, denoting the number of testcases.

For each testcase, the first line contains two integers n <= 10^5 and C <= 10^9.
n lines follow. The i-th of them contains three integers Vi, Xi, Di. Vi denotes the initial velocity of ball i. Xi denotes the initial position of ball i. Di denotes the direction ball i moves in.

The next line contains an integer q <= 10^5, denoting the number of queries.
q lines follow. Each line contains two integers t <= 10^9 and 1<=k<=n.
1<=Vi<=10^5,1<=Xi<=10^9

Output

For each query, print a single line containing the answer with accuracy of 3 decimal digits.

Sample Input

1
3 7
3 3 1
3 10 -1
2 7 1
3
2 3
1 2
3 3

Sample Output

6.083
4.796
7.141

Author

学军中学

题意:在光滑的水平的导轨上有一些球,这些球的速度与加速度之间的关系为v×a=c 给你球的初始的速度,位置和方向。但球相撞时为弹性碰撞。有q次询问,每次询问t是第k小的速度是多少。

思路:这道题的处理类似poj的蚂蚁的题,由于是弹性碰撞,所以在处理的时候是直线的,又由于a×v=c,我们可以得到

a=cv
dvdt=cv
所以
v dv=c dtv2=2ctv=2ct
我们算出初速的为零的时候速度与时间的之间的关系,那么我们可以处理出每个球到达指定的初速度的所需要的时间,然后排序(函数是单调的)。处理就行了。

#include <bits/stdc++.h>using namespace std;const int Max  = 1e5+100;double a[Max];int main(){    int T;    int n,m,k;    double c,x,d;    scanf("%d",&T);    while(T--)    {        scanf("%d %lf",&n,&c);        for(int i = 0;i<n;i++)        {            scanf("%lf %lf %lf",&a[i],&d,&x);            a[i] = a[i]*a[i]/(2*c);        }        sort(a,a+n);        scanf("%d",&m);        while(m--)        {            scanf("%lf %d",&d,&k);            printf("%.3f\n",sqrt((a[k-1]+d)*c*2));        }    }    return 0;}

HDU【5828】——Rikka with Sequence


Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has an array A with n numbers. Then he makes m operations on it.

There are three type of operations:

1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊A−−√[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]

It is too difficult for Rikka. Can you help her?

Input

The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.

For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.

It is guaranteed that 1<=A[i],x<=100000.

Output

For each operation of type 3, print a lines contains one number – the answer of the query.

Sample Input

1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5

Sample Output

5
6

Author

学军中学

题意很明显了,就不解释了。比赛的时候在队友强行对拍的情况下,找到了手残的地方。对于区间和和区间加就不解释了,线段树很容易解决。关键在与区间开根,由于是向下取整,所以在执行开根操作以后,可能会出现两个区间的数是完全一样的,那么我们就可以将这些区间的数一样的区间进行合并,当再执行区间开根操作的时候,就可以区间的操作。不过要注意一下细节,比赛的时候代码,感觉写的有点搓orz。。后来听说可以卡掉,有时间再重写。

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <queue>#include <vector>#include <stack>#include <map>#include <algorithm>#include <cmath>#include <ctime>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const LL INF = 0x3f3f3f3f;const double eps = 1e-8;const LL mod = 1000000007;const LL Max = 1e5+100;struct Node{    LL sum,lazy,bing;}Tr[Max*5];LL a[Max];void up(LL st){    if(Tr[st<<1].bing == Tr[st<<1|1].bing && Tr[st<<1].bing)    {        Tr[st].bing = Tr[st<<1].bing;    }    else Tr[st].bing = 0;    Tr[st].sum  = Tr[st<<1].sum+Tr[st<<1|1].sum;}void down(LL st,LL l,LL r)//向下更新比较的麻烦{    LL mid = (l+r)>>1;    if(Tr[st].bing)    {        Tr[st<<1|1].bing = Tr[st<<1].bing = Tr[st].bing;        Tr[st<<1].sum=(Tr[st].bing*(mid-l+1));        Tr[st<<1|1].sum=(Tr[st].bing*(r-mid));    }    if(Tr[st].lazy)    {        if(!Tr[st<<1].bing)        {            Tr[st<<1].lazy +=Tr[st].lazy;        }        else Tr[st<<1].bing+=Tr[st].lazy;        if(!Tr[st<<1|1].bing)        {            Tr[st<<1|1].lazy += Tr[st].lazy;        }        else Tr[st<<1|1].bing+=Tr[st].lazy;        Tr[st<<1|1].sum+=(Tr[st].lazy*(r-mid));        Tr[st<<1].sum +=(Tr[st].lazy*(mid-l+1));        Tr[st].lazy = 0;    }}void Init(LL l,LL r,LL st){    Tr[st].sum = 0; Tr[st].lazy = 0; Tr[st].bing = 0;    if(l == r)    {        Tr[st].sum = a[l];        Tr[st].bing= a[l];        return ;    }    LL mid = (l+r)>>1;    Init(l,mid,st<<1);    Init(mid+1,r,st<<1|1);    up(st);}void add(LL l,LL r,LL st,LL L,LL R,LL va){    if(l == L&& R== r)    {        Tr[st].sum +=(va*(r-l+1));        if(Tr[st].bing){            Tr[st].bing+=va;        }        else Tr[st].lazy+=va;        return ;    }    down(st,l,r);    LL mid = (l+r)>>1;    if(R<=mid) add(l,mid,st<<1,L,R,va);    else if(L>mid) add(mid+1,r,st<<1|1,L,R,va);    else    {        add(l,mid,st<<1,L,mid,va);        add(mid+1,r,st<<1|1,mid+1,R,va);    }    up(st);}void Sqrt(LL l,LL r,LL st,LL L,LL R){    if(l==L &&R == r && Tr[st].bing)    {        Tr[st].bing = (LL)sqrt(Tr[st].bing);        Tr[st].sum = Tr[st].bing*(R-L+1);        Tr[st].lazy = 0;        return ;    }    down(st,l,r);    LL mid = (l+r)>>1;    if(R<=mid) Sqrt(l,mid,st<<1,L,R);    else if(L>mid) Sqrt(mid+1,r,st<<1|1,L,R);    else    {        Sqrt(l,mid,st<<1,L,mid);        Sqrt(mid+1,r,st<<1|1,mid+1,R);    }    up(st);}LL Qu(LL l,LL r,LL st,LL L,LL R){    if(L== l &&R == r) return Tr[st].sum;    down(st,l,r);    LL mid = (l+r)>>1;    if(R<=mid) return Qu(l,mid,st<<1,L,R);    else if(L>mid) return Qu(mid+1,r,st<<1|1,L,R);    else    {        return Qu(l,mid,st<<1,L,mid)+Qu(mid+1,r,st<<1|1,mid+1,R);    }    up(st);}int main(){    LL T,n,m;    LL op,l,r,va;    scanf("%I64d",&T);    while(T--)    {        scanf("%I64d %I64d",&n,&m);        for(LL i = 1;i<=n;i++) scanf("%I64d",&a[i]);        Init(1,n,1);        while(m--)        {            scanf("%I64d",&op);            if(op == 1)            {                scanf("%I64d %I64d %I64d",&l,&r,&va);                add(1,n,1,l,r,va);            }            else if(op == 2)            {                scanf("%I64d %I64d",&l,&r);                Sqrt(1,n,1,l,r);            }            else if(op == 3)            {                scanf("%I64d %I64d",&l,&r);                printf("%I64d\n",Qu(1,n,1,l,r));            }        }    }    return 0;}

HDU【5831】——Rikka with Parenthesis II


Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Correct parentheses sequences can be defined recursively as follows:
1.The empty string “” is a correct sequence.
2.If “X” and “Y” are correct sequences, then “XY” (the concatenation of X and Y) is a correct sequence.
3.If “X” is a correct sequence, then “(X)” is a correct sequence.
Each correct parentheses sequence can be derived using the above rules.
Examples of correct parentheses sequences include “”, “()”, “()()()”, “(()())”, and “(((())))”.

Now Yuta has a parentheses sequence S, and he wants Rikka to choose two different position i,j and swap Si,Sj.

Rikka likes correct parentheses sequence. So she wants to know if she can change S to a correct parentheses sequence after this operation.

It is too difficult for Rikka. Can you help her?

Input

The first line contains a number t(1<=t<=1000), the number of the testcases. And there are no more then 10 testcases with n>100

For each testcase, the first line contains an integers n(1<=n<=100000), the length of S. And the second line contains a string of length S which only contains ‘(’ and ‘)’.

Output

For each testcase, print “Yes” or “No” in a line.

Sample Input

3
4
())(
4
()()
6
)))(((

Sample Output

Yes
Yes
No

Hint

For the second sample input, Rikka can choose (1,3) or (2,4) to swap. But do nothing is not allowed.

Author

学军中学

将左括号看做1,右括号为-1。搞一发

#include <bits/stdc++.h>using namespace std;int T,n;char str[100100];bool ok(){    int Mi = n;    int sum = 0;    for(int i = 0; i<n; i++)    {        sum+=(str[i] == '('?1:-1);        Mi = min(Mi,sum);    }    if(sum!=0) return false;    if(n == 2) return str[0] == ')';    return Mi>=-2;}int main(){    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        scanf("%s",str);        if(ok()) printf("Yes\n");        else printf("No\n");    }    return 0;}
0 0