2017 Multi-University Training Contest

来源:互联网 发布:超链接调用js传递参数 编辑:程序博客网 时间:2024/06/03 21:44

1005

给定正整数aa,求对于所有正整数bba\mod bamodb有多少种可能的结果。1\leq a\leq10^91a109

显然小于<a/2的每个非负整数c都是可能成为余数的,取b=a-c即可,另外a本身也能成为余数,而其他数显然都不可能。

#include<cstdio>int main(){    int T;    long long a;    scanf("%d",&T);    while (T--)    {        scanf("%lld",&a);        printf("%lld\n",(a+1)/2+1);    }} 

1008

平面直角坐标系上有nn个整点,第ii个点有一个点权val_ivali,坐标为(x_i,y_i)(xi,yi),其中不存在任意两点连成的直线经过原点。这些整点两两之间连有一条线段,线段的权值为其两端点的权值之积。你需要作一条过原点而不过任意一个给定整点的直线,使得和这条直线相交的线段的权值和最大。1\leq n\leq5\times10^4,1\leq val_i\leq10^4,|x_i|,|y_i|\leq10^91n5×104,1vali104,xi,yi109

对于一条直线,线段权值和实际上就等于其两边点权和的乘积,所以把所有点按极角排个序,然后扫一圈就好了。

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <cmath>#include <map>#include <vector>#include <cctype>#include <set>#include "iostream"using namespace std;const int INF = 2147483640;const double eps = 1e-7;typedef long long ll;const int MAXN = 50000 + 100;struct point{    double x,y;    int v;    double k;    bool up;}p[MAXN];bool cmp(point a,point b){    return a.k>b.k;}bool up[MAXN];ll ans;void init(){    memset(up,0,sizeof up);}int main(){    //freopen("input.txt","r",stdin);    int t;    while(cin>>t)    {        while(t--)        {            init();            int n;            cin>>n;            for (int i = 0; i < n; ++i)            {                scanf("%lf %lf %d",&p[i].x,&p[i].y,&p[i].v);                if((int)p[i].x!=0)p[i].k=p[i].y/p[i].x;                if((int)p[i].x<0) p[i].up=1;                else p[i].up=0;                if((int)p[i].x==0 && p[i].y>0) p[i].up=1,p[i].k=1e9+100;                if((int)p[i].x==0 && p[i].y<0) p[i].up=0,p[i].k=-1*(1e9+100);            }            ll t1=0,t2=0;            sort(p,p+n,cmp);            for(int i=0;i<n;++i)                if(p[i].up) t1+=p[i].v;            else t2+=p[i].v;            ans=t1*t2;            //sort(p,p+n,cmp);            for(int i=0;i<n;++i)            {                if(p[i].up)                {                    p[i].up=0;                    t1-=p[i].v;                    t2+=p[i].v;                }else{                    p[i].up=1;                    t1+=p[i].v;                    t2-=p[i].v;                }                ans=max(ans,t1*t2);            }            cout<<ans<<endl;        }    }    return 0;}

1010

有一个长度为nn的整数序列{a_n}{an},对其做mm次前缀异或和,求最终的序列。1\leq n\leq2\times10^5,1\leq m\leq10^9,0\leq a_i\leq2^{30}-11n2×105,1m109,0ai2301

可以发现做m次后,位置为x的初始值对位置为y的最终值的贡献次数是一个只和m与y-x相关的组合式,而我们只关注这个次数的奇偶性。考虑Lucas定理,C(a,b)是奇数当且仅当把a,b二进制表达后b中1的位置是a中1的位置的子集,于是这里所有满足条件的b有很好的性质,对每一个二进制位独立处理就能算出答案。

#include<cstdio>int T,n;long long m,k;long long a[200005];int main(){    scanf("%d",&T);    while (T--)    {       scanf("%d %lld",&n,&m);       for (int i=1;i<=n;i++) scanf("%lld",&a[i]);       k=1;              while(k * 4 <= m)             k *= 4;          while(m)          {             while(m>=k)             {                for(int i=k+1;i<=n;i++) a[i] ^= a[i-k];                m-=k;             }            k/=4;          }                 for (int i=1;i<n;i++) printf("%lld ",a[i]);       printf("%lld\n",a[n]);    }} 

1011

以下是Kolakoski数列:$1,2,2,1,1,2,1,2,2,1,2,2,1,1,2,1,1,2,2,1……$,这个数列仅有1122组成,并且第一项是11。同时还满足一个性质,如果把相邻且相同的项看成一组,可以得到$1,22,11,2,1,22,1,22,11,2,11,22,1……$,计算每一组项的数量,则能得到这个序列本身。这个数列是可以被唯一确定的,请求出它的第nn项。1\leq n\leq10^71n107

考虑如何模拟数列的构造,只要在拿一个指针在序列中间扫的同时,往序列末端加数就可以了。

#include "stdio.h"#include "iostream"#include "cstring"#include "cmath"using namespace std;typedef long long ll;struct point{    double x,y;    point(double xx,double yy):x(xx),y(yy){}};double getdis(point a,point b){    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}int arr[10000100];void init(){    memset(arr,0,sizeof arr);    arr[1]=1;    arr[2]=2;    arr[3]=2;    int index=3;    int cur=1;    for(int i=4;i<10000100;)    {        for(int j=0;j<arr[index];++j,++i)            arr[i]=cur;        index++;        if(cur==1)            cur=2;        else cur=1;    }    // for(int i=1;i<100;++i)    //     printf("%d ",arr[i] );}int main(int argc, char const *argv[]){    int t;    // cin>>t;    init();    while(cin>>t)    {        while(t--){        int n;        scanf("%d",&n);        printf("%d\n",arr[n]);        }    }      return 0;}

原创粉丝点击