Codeforces Round #365 Div.2[11110]

  血崩,做了俩小时只过了一道题,低级错误疯狂的犯。幸好不知道为什么貌似没算分,不然rating要爆炸。

  A:呵呵

#include<stdio.h>
#include<stdlib.h>
int main()
{
    //freopen("input.txt","r",stdin) ;
    int N;
    scanf("%d",&N);
    int x=0,y=0;
    for (int i=1;i<=N;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        if (a>b) x++;
        if (a<b) y++;
    }
    if (x>y) printf("Mishka\n");
    else if (x<y) printf("Chris\n");
    else printf("Friendship is magic!^^\n");
    //fclose(stdin);
    return 0;
}

  B:先算最外边的环路,然后算capital到非capital,再算capital到capital。注意算后两步的时候要确定两个点是否相邻,如果相邻则不必计算。capital到capital的计算结果要除以2。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
int ABS(int x)
{
    if (x>0) return x;
    else return -1*x;
}
bool v[150000];
int c[150000],p[150000];
int main()
{
    int N,K;
    while (cin>>N>>K)
    {
        memset(v,false,sizeof(v));
        for (int i=1;i<=N;i++) cin>>c[i];
        for (int i=1;i<=K;i++)
        {
            cin>>p[i];
            v[p[i]]=true;
        }
        unsigned long long ans=0;
        for (int i=1;i<N;i++) ans+=c[i]*c[i+1];
        if (N!=1) ans+=c[N]*c[1];
        long long sum1=0,sum2=0;
        for (int i=1;i<=N;i++)
        {
            if (v[i]) sum1+=c[i];
            else sum2+=c[i];
        }
        for (int i=1;i<=K;i++)
        {
            int l=p[i]-1,r=p[i]+1;
            if (l==0) l=N;
            if (r==N+1) r=1;
            long long tmp=sum2;
            if (!v[l]) tmp-=c[l];
            if (!v[r]) tmp-=c[r];
            ans+=tmp*c[p[i]];
        }
        long long add=0;
        for (int i=1;i<=K;i++)
        {
            int l=p[i]-1,r=p[i]+1;
            if (l==0) l=N;
            if (r==N+1) r=1;
            long long tmp=sum1;
            tmp-=c[p[i]];
            if (v[l]) tmp-=c[l];
            if (v[r]) tmp-=c[r];
            add+=tmp*c[p[i]];
        }
        ans+=add/2;
        cout<<ans<<endl;
    }
    return 0;
}

  C:可以想象成车子不动,人具有恒定的水平方向分速度v,竖直方向分速度为0~u。只需使人的位移线与多边形不相交就等价于使车撞不到人。人要避开车子有两种方式,一种是曲线位于多边形上方,这种情况下人可以直接从0时刻开始以最高速度通过。条件是多边形所有顶点与原点的斜率小于u/v。否则,曲线应从多边形下方通过。首先找到到原点斜率最小的一个顶点,如果这个点到原点的斜率大于等于u/v,则人也可以最高速度直接通过。否则人先走到这个点,然后计算逆时针的下一个顶点到这个点的斜率,如果斜率比当前的斜率大,则人可以加速,并以相应的速度移动到与下一个点横坐标相同的位置,直到斜率超过最大斜率或斜率小于0,则剩余路程直接以最大速度通过。

#include<stdio.h>
#include<stdlib.h>
double ABS(double x)
{
    if (x>0) return x;
    else return -1*x;
}
double xl(double x1,double y1,double x2,double y2)
{
    if (ABS(x2-x1)<1e-10) return 1e15;
    return (y2-y1)/(x2-x1);
}
double x[12000],y[12000];
int main()
{
    int N;
    double w,v,u;
    while (scanf("%d%lf%lf%lf",&N,&w,&v,&u)!=EOF)
    {
        bool neg=false;
        for (int i=1;i<=N;i++)
        {
            scanf("%lf%lf",&x[i],&y[i]);
            if (x[i]<=0) neg=true;
        }
        double ans=0;
        double maxxl=1e-15,minxl=1e15;
        int maxp,minp;
        for (int i=1;i<=N;i++)
        {
            double tmp=xl(0,0,x[i],y[i]);
            if (tmp>maxxl)
            {
                maxxl=tmp;
                maxp=i;
            }
            if (tmp<minxl && x[i]>0)
            {
                minxl=tmp;
                minp=i;
            }
        }
        double stdxl=u/v;
        if ((stdxl>=maxxl && neg==false) || minxl>stdxl)
        {
            ans=w/u;
            printf("%.8lf\n",ans);
            return 0;
        }
        int p=minp;
        double curxl=minxl,cx=x[p],cy=y[p];
        ans=x[p]/v;
        while (curxl<stdxl)
        {
            p++;
            if (p==(N+1)) p=1;
            double tmpx=xl(cx,cy,x[p],y[p]);
            if (tmpx<0)
            {
                ans+=(w-cy)/u;
                printf("%.8lf\n",ans);
                return 0;
                break;
            }
            if (tmpx>stdxl) tmpx=stdxl;
            curxl=tmpx;
            ans+=(x[p]-cx)/v;
            cy+=((x[p]-cx)*curxl);
            cx=x[p];
        }
        if (cy<w) ans+=(w-cy)/u;
        printf("%.8lf\n",ans);
    }
    return 0;
}

  D:由于异或自身的结果为0,所以从l到r区间内所有数的异或和等于其中出现奇数次的数的异或和。为了求出出现偶数次数的数的异或和,只需将所有数的异或和再异或上l到r内所有出现过的数的异或和,就可以将本来出现偶数次数的变为奇数次,而奇数次则变为偶数次,得到所求答案。将所有询问按r排序,用数组f[x]保存从1到x所有出现过的数的异或和。当一个数再次出现时,以最新的位置为准,从而使f[r]^f[l-1]的值即为从l到r出现的所有种类数的异或和。

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <bitset>
#include <math.h>
#include <vector>
#include <string>
#include <stdio.h>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
struct node
{
    int l,r,id;
    bool operator < (const node a)
    {
        return r<a.r;
    }
}q[1010000];
map<int,int> M;
int N,a[1010000],f[1010000],pre[1010000],xo[1010000],ans[1010000];
void add(int x,int y)
{
    for (;x<=N;x+=x&-x) f[x]^=y;
}
int get(int x)
{
    int ret=0;
    for (;x;x-=x&-x) ret^=f[x];
    return ret;
}
int main()
{
    int i,k,m;
    scanf("%d",&N);
    for (i=1;i<=N;i++)
    {
        scanf("%d",&a[i]);
        xo[i]=xo[i-1]^a[i];
    }
    for (i=1;i<=N;i++)
    {
        pre[i]=M[a[i]];
        M[a[i]]=i;
    }
    scanf("%d",&m);
    for (i=1;i<=m;i++)
    {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].id=i;
    }
    sort(q+1,q+m+1);
    for (k=1,i=1;i<=m;i++)
    {
        for (;k<=N&&k<=q[i].r;k++)
        {
            if (pre[k]) add(pre[k],a[k]);
            add(k,a[k]);
        }
        ans[q[i].id]=xo[q[i].r]^xo[q[i].l-1]^get(q[i].r)^get(q[i].l-1);
    }
    for (i=1;i<=m;i++)
        printf("%d\n",ans[i]);
    return 0;
}

时间: 2024-11-12 17:54:29

Codeforces Round #365 Div.2[11110]的相关文章

Codeforces Round #365 (Div. 2) D - Mishka and Interesting sum(离线树状数组)

http://codeforces.com/contest/703/problem/D 题意: 给出一行数,有m次查询,每次查询输出区间内出现次数为偶数次的数字的异或和. 思路: 这儿利用一下异或和的性质,在一个区间中,我们如果把所有数字都异或的话,可以发现最后偶数次的数字异或后都变成了0,只剩下了奇数次的数字异或. 举个例子,{1,2,3,2,3,5} 异或和是1^2^3^2^3^5=1^5 因为最后要计算偶数次数字的异或和,那么最后我们只需要再异或上该区间内所有不同数字即可. 那么我们可以先

Codeforces Round #365 (Div. 2) C

链接:http://codeforces.com/problemset/problem/703/C 分析:  这题其实是个大水题,只要短短的几行就可以搞定的, 首先需要直觉判断一点,就是只要判断最左边的点和最下面的点 以及和他们相邻边的右边的点 第二部我们就需要判断人与这两个边有没有交点,如果人与上面的有交点,那么人肯定就需要在下面的那条边等待  等待的时间是 max(x - y*1.0*v/u) 那么我们所需要做的还有一步就是判断就是需不需要等待 ,当min(x - y*1.0*v/u) >=

Codeforces Round #365 (Div. 2) A

Description Mishka is a little polar bear. As known, little bears loves spending their free time playing dice for chocolates. Once in a wonderful sunny morning, walking around blocks of ice, Mishka met her friend Chris, and they started playing the g

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和Xor[i],表示1~i的xor和.因为num^num=0,所以Xor[r] ^ Xor[l - 1]求的是l~r之间出现奇数次的数字xor和. 那怎么求偶数次的呢,那我们可以先求l到r之间不重复出现数字的xor(比如1 1 2 求的是1 ^ 2),然后再xor以上求出的Xor[r] ^ Xor[l

Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum 树状数组

D. Mishka and Interesting sum 链接: http://codeforces.com/problemset/problem/703/D 题意: 给一个序列 每次询问一个区间 求区间中出现次数为偶数次的数的异或和 代码: 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<map> 5 using namespace std; 6 7 str

Codeforces Round #367 Div. 2 [11110]

#include <iostream> #include <map> #include <math.h> using namespace std; int main() { double a, b; cin >> a >> b; int n; cin >> n; double MIN = 1e10; while (n--) { double x, y, v; cin >> x >> y >> v;

Codeforces Round #365 (Div. 2)

5/5 这场CF有毒啊!!好在不计rating(/▽╲) 题A Mishka and Game 题意:略 题解:略 题B Mishka and trip 题意:给你一个图,告诉你一开始围成一个环,然后每个点都有自己的权值,然后两个点的路径权值为这两个点的乘积,然后告诉你某些点是中心点,然后问你权值之和. 题解:这题有点意思,第一题太水了,反而觉得不太好. (1)先算出对于那些中心点的所有权值,这样会重复,画图发现重了的地方就是多算了一次这些中心点形成的完全图,所以只要(2)减去这些中心点形成的完

Codeforces Round #363 Div.2[11110]

好久没做手生了,不然前四道都是能A的,当然,正常发挥也是菜. A:Launch of Collider 题意:20万个点排在一条直线上,其坐标均为偶数.从某一时刻开始向左或向右运动,速度为每秒1个单位长度.输入给出每个点的坐标及其移动的方向,求发生第一次碰撞的时间,若不会碰撞,则输出-1 最先发生碰撞的是一定是初始时相邻的两个点,因此只需对每个点循环一边,判断其是否会与下一个点碰撞,并求出其时间即可. #include<stdio.h> #include<stdlib.h> int

Codeforces Round #365 (Div. 2) B

Description Little Mishka is a great traveller and she visited many countries. After thinking about where to travel this time, she chose XXX — beautiful, but little-known northern country. Here are some interesting facts about XXX: XXX consists of n