2016-11-15 考试总结

来源:互联网 发布:怎样翻墙上外网 知乎 编辑:程序博客网 时间:2024/05/20 05:25

又是一天的考试,又是一天的爆0。

Day 2

T1 Calc

一道数学竞赛题,非常的神奇。主要是要把题目所求转化为组合计数。
原题的公式是
nk1=0nk2=0nkm=0m1j=1(kj+1kj)

可以得到公式
ANS=nk=0mk=mn+11m1

最后用费马小定理与逆元完成计算。

#include<bits/stdc++.h>#define mod 1000000007using namespace std;long long sum=1;void ksm(long long a,long long b){    if(b==1)    {        sum=(sum*a)%mod;        return;    }    if(b%2==1)        sum=(sum*a)%mod;    a=(a*a)%mod;    b=b/2;    ksm(a,b);}int main(){    int n,m;    cin>>n>>m;    ksm(m,n+1);    long long sum1=sum-1;    sum=1;    ksm(m-1,mod-2);    cout<<(long long)((sum1)*(sum))%mod;}

T2 Chess

是全卷最难的一道题,因为每一个车会控制一行和一列,所以将列和行分开计算。
使用两个map进行维护。
时间复杂度O(nlogn2)

#include <iostream>#include <cstdio>#include <algorithm>#include <map>#include <cctype>using namespace std;int n,k,q;long long Sol;map<int,int> RCnt,CCnt;map<int,int> RXor,CXor;map<pair<int,int>,int> Rook;void MoveRook(int r,int c,int Val) {    int Rxor=RXor[r],Cxor=CXor[c];    Sol-=n-RCnt[Cxor];    Sol-=n-CCnt[Rxor];    --RCnt[Rxor];    Rxor=RXor[r]^=Val;    ++RCnt[Rxor];    --CCnt[Cxor];    Cxor=CXor[c]^=Val;    ++CCnt[Cxor];    Sol+=n-CCnt[Rxor];    Sol+=n-RCnt[Cxor];    Rook[pair<int,int>(r,c)]^=Val;}void Init() {    cin>>n>>k>>q;    RCnt[0]=CCnt[0]=n;    for(int i=0;i^k;++i) {        int r,c,Val;        cin>>r>>c>>Val;        --r;        --c;        MoveRook(r,c,Val);    }}void Solve() {    while(q--) {        int r1,c1,r2,c2;        cin>>r1>>c1>>r2>>c2;        --r1;        --c1;        --r2;        --c2;        int RookVal=Rook[pair<int,int>(r1,c1)];        MoveRook(r1,c1,RookVal);        MoveRook(r2,c2,RookVal);        cout<<Sol<<endl;    }}int main() {    Init();    Solve();    return 0;}

T3 Function

因为一个数被取模最多logx2次,所以关键便是找到下一次被mod的位置即可。

#include<cstdio>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<iostream>#include<cctype>using namespace std;int l,r,now,pl,n,m;int num[100010];struct node{    int min;}tree[400010];inline void R(int &v){    char c=0;    v=0;    while(!isdigit(c))        c=getchar();    while(isdigit(c))    {        v=(v<<3)+(v<<1)+(c^'0');        c=getchar();    }}void updata(int k){    tree[k].min=min(tree[k<<1].min,tree[k<<1|1].min);}void read(){    R(n);    for(int i=1;i<=n;++i)        R(num[i]);}void build(int k,int s,int t){    if(s==t)    {        tree[k].min=num[s];        return ;    }    int mid=(s+t)>>1;    build(k<<1,s,mid);    build(k<<1|1,mid+1,t);    updata(k);}void query(int k,int s,int t,int l,int r){    if(tree[k].min>now)        return ;    if(pl<=r)        return ;    if(l<=s&&t<=r)    {        if(s==t)        {            pl=s;            return ;        }         int mid=(s+t)>>1;        query(k<<1,s,mid,l,r);        query(k<<1|1,mid+1,t,l,r);    }    int mid=(s+t)>>1;    if(l<=mid)        query(k<<1,s,mid,l,r);    if(r>mid)        query(k<<1|1,mid+1,t,l,r);}int main(){    read();    build(1,1,n);    R(m);    while(m--)    {        R(l);        R(r);        now=num[l];        l++;        while(now&&l<=r)        {            pl=n+1;            query(1,1,n,l,r);            if(pl>r)                break;            now%=num[pl];            l=pl+1;        }        cout<<now<<'\n';    }    return 0;}
1 0