2017 ACM-ICPC 亚洲区(西安赛区)网络赛

Posted Roni

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017 ACM-ICPC 亚洲区(西安赛区)网络赛相关的知识,希望对你有一定的参考价值。

  •  A. Tree 题库链接
    • 通过率: 41.8 %
    • 通过人数: 51
  •  B. Coin 题库链接(√)
     就是求 ((p-q)/p+q/p*x)^k 的偶次项系数之和  
     代入 x=1, -1 加加减减就行了 
    • 通过率: 73.25 %
    • 通过人数: 734
  •  C. Sum 题库链接(√)(
     1000000100000010000001000001
    这样,放233个1就好了 
     C = "1000000" * 233 
    • 通过率: 91.44 %
    • 通过人数: 1121
  •  D. Brain-baffling Game 题库链接
    • 通过率: 4.55 %
    • 通过人数: 1
  •  E. Maximum Flow 题库链接(√)
     E 得知道最大流等于最小割
    然后 0 到 n-1 肯定要割
    其他点和 0 以及 n-1 都有边肯定要割一条
    然后发现最高位是 1 的割和 n-1 连的,否则割和 0 连的
    然后发现这已经割好了 //
     其实也觉得E恐怕是一个数位dp,但是还是打表
     做差,差为4的整数幂+1
    每个数的出现有周期
    除了最开始的两次
    但是那两次同样有规律 
     lowbit找规律

    规律看两两之间的差
    4^n+3出现的规律就是把一个数的二进制表示的情况下通过删除或插入或替代的方法从n到n+1的次数

     

    技术分享
    • 通过率: 62.16 %
    • 通过人数: 391
  •  F. Trig Function 题库链接(√)
  • (chebyshev+切比雪夫多项式 
     求出k然后比较分子分母大小然后从小的开始+=2算出双阶层就好了 
    • 通过率: 74.08 %
    • 通过人数: 463
  •  G. Xor 题库链接  (hdu5840 分块,K大于sqrtn的暴力跳,小于sqrtn的预处理跳到根的值 
     k 大暴力跳
    k 小就预处理一下加加减减 
    • 通过率: 56.87 %
    • 通过人数: 149
  •  H. Music 题库链接
    • 通过率: 36.36 %
    • 通过人数: 4
  •  I. Barty‘s Computer 题库链接(裸AC自动机,
     前一半就是多校解法,匹配到之后hash判断砍一半扔进ac自动机,flag标记后半串,然后查询的时候,1和2 用ac自动机匹配,匹配到了用hash比3 4 
    I 转化成五维偏序然后 bitset 裸的五维数点 
     转五维数点直接 sort + lower_bound 就行了 
     暴力匹配 匹配X4 
    • 通过率: 65.58 %
    • 通过人数: 101
  •  J. Easy Problem 题库链接
    • 通过率: 40 %

 

BCEF

C:

技术分享
#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

int main()
{
    int t,x;
    scanf("%d",&t);
    while(t--){
        cin>>x;
        printf("1");
        for(int i=2;i<=233;i++)
        {
            printf("0000001");
        }
        printf("\n");
    }
    return 0;
}
规律

B:

技术分享
#include <iostream>
#include <cstdio>
using namespace std;
int mod=1e9+7;
typedef long long ll;


long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if(a==0&&b==0) return -1;//无最大公约数
    if(b==0){x=1;y=0;return a;}
    long long d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

long long inv(long long a,long long n)
{
    long long x,y;
    long long d=exgcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}

ll pow(int x,int n)  //注意n等于0的时候
{
    ll a=x;
    ll ans=1;
    while (n)
    {
        if (n&1) ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;//效果跟n/=2;一样
    }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll p,q,k;
        ll x,y;
        scanf("%lld%lld%lld",&p,&q,&k);
        if(p>q)
        {
            swap(q,p);
        }
        x=pow(q-2*p,k);
        y=pow(q,k);
        x=(x+y)%mod;
        y=(2*y)%mod;

        printf("%lld\n",(x*inv(y,mod))%mod);
    }
}
1
技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
const int mod = 1e9+7;
long long _pow(long long a,long long b)
{
    long long res = 1;
    while(b)
    {
        if(b&1)
            res = res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if(a==0&&b==0) return -1;//无最大公约数
    if(b==0){x=1;y=0;return a;}
    long long d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

long long inv(long long a,long long n)
{
    long long x,y;
    long long d=exgcd(a,n,x,y);
    if(d==1) return (x%n+n)%n;
    else return -1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int p,q,k;
        scanf("%d%d%d",&p,&q,&k);
        if(p>q){
            int temp=p;
            p=q;
            q=temp;
        }
        long long x=_pow(q-2*p,k);
        long long y=_pow(q,k);
        x=y+x;
        y=2*y;
        printf("%lld\n",x*inv(y,mod)%mod);
    }
    return 0;
}
2

E:

技术分享
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll sum[100];
ll la[100];
ll two[100];
int main()
{
    sum[0]=1;
    la[0]=1;
    two[0]=1;
    for(int i=1; i<=64; i++)
    {
        two[i]=two[i-1]*2ll;
        sum[i]=(sum[i-1]*2%mod+la[i-1]*3%mod)%mod;
        la[i]=la[i-1]*4%mod;
    }
    ll n;
    while(~scanf("%lld",&n))
    {

        n--;
        ll pos;
        for(ll i=62; i>=0; i--)
        {
            if(n>=two[i])
            {
                pos=i;
                break;
            }
        }
        ll ans=n%mod;
//        cout<<pos<<endl;
        pos=(1ll<<pos);
        n-=pos;
        ans+=((1ll*pos/2ll)%mod)*((pos-1ll)%mod);
        ans%=mod;
        for(ll i=0; i<63; i++)
        {
            if(n&(1ll<<i))
                ans+=sum[i];
            ans%=mod;
        }
        printf("%lld\n",ans%mod);
    }
}
1
技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;

const int MAXN = 30010;

string lib[MAXN];
int tot;

int cmpa(string &str, string &a){
    for(int i = 0; i < a.length(); ++i){
        if(str[i] != a[i]){
            return 0;
        }
    }
    return 1;
}

int cmpd(string &str, string &d){
    for(int i = 1; i <= d.length(); ++i){
        if(str[str.length() - i] != d[d.length() - i]){
            return 0;
        }
    }
    return 1;
}

int cmpbc(string &str, string &b, string &c){
    int mid = str.length() / 2;
    for(int i = 0; i < c.length(); ++i){
        if(str[mid + i] != c[i]){
            return 0;
        }
    }
    for(int i = 1; i <= b.length(); ++i){
        if(str[mid - i] != b[b.length() - i]){
            return 0;
        }
    }
    return 1;
}

int main(){
    ios::sync_with_stdio(false);
    int T, q;
    for(cin >> T; T && cin >> q; --T){
        tot = 0;
        int ctrl;
        for (int k = 0; k < q; ++k)
        {
            cin >> ctrl;
            if (ctrl == 1)
            {
                cin >> lib[tot++];
            }
            else
            {
                string a, b, c, d;
                cin >> a >> b >> c >> d;
                int maxLen = a.length() + b.length();
                if (c.length() + d.length() > maxLen)
                    maxLen = c.length() + d.length();
                maxLen *= 2;
                int cnt = 0;
                for (int i = 0; i < tot; ++i)
                {
                    if (lib[i].length() >= maxLen && lib[i].length() % 2 == 0)
                    {
                        if (cmpa(lib[i], a) && cmpd(lib[i], d) && cmpbc(lib[i], b, c))
                        {
                            ++cnt;
                        }
                    }
                }
                cout << cnt << endl;
            }
        }
    }
    return 0;
}
2

F:【分析】:

http://www.docin.com/p-385138324.html?qq-pf-to=pcqq.group加个费马小定理 乘逆元就可以了

技术分享
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<utility>
#include<numeric>
#include<iterator>
#include<algorithm>
#include<functional>
#include<ctime>
#include<cassert>
using std::cin;
using std::cout;
using std::endl;
typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int,int> P;
#define FOR(i,init,len) for(int i=(init);i<(len);++i)
#define For(i,init,len) for(int i=(init);i<=(len);++i)
#define fi first
#define se second
#define pb push_back
#define is insert
namespace IO {
    inline char getchar() {
        static const int BUFSIZE=5201314;
        static char buf[BUFSIZE],*begin,*end;
        if(begin==end) {
            begin=buf;
            end=buf+fread(buf,1,BUFSIZE,stdin);
            if(begin==end) return -1;
        }
        return *begin++;
    }
}
inline void read(int &in) {
    int c,symbol=1;
    while(isspace(c=IO::getchar()));
    if(c==-) { in=0;symbol=-1; }
    else in=c-0;
    while(isdigit(c=IO::getchar())) { in*=10;in+=c-0; }
    in*=symbol;
}
inline int read() { static int x;read(x);return x; }
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; }
ll lcm(ll a,ll b) { return a/gcd(a,b)*b; }

const ll mod=998244353LL;
const int maxm=1e4+10;
ll qpow(ll a,ll b) {
    ll ans=1;
    while(b) {
        if(b&1) ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
ll f[maxm],invf[maxm];
ll n,m;

int main() {
#ifdef MengLan
    int Beginning=clock();
    //freopen("in","r",stdin);
    //freopen("out","w",stdout);
#endif // MengLan

    f[0]=1;
    FOR(i,1,maxm) f[i]=f[i-1]*i%mod;
    invf[maxm-1]=qpow(f[maxm-1],mod-2);
    for(int i=maxm-2;i>=0;--i) invf[i]=invf[i+1]*(i+1)%mod;
    while(cin>>n>>m) {
        if((n&1)^(m&1)) { puts("0");continue; }
        if(m>n) { puts("0");continue; }
        if(m==0) { puts("998244352");continue; }
        ll ans=1;
        for(ll i=n-m+2;i<=n+m-2;i+=2) { ans*=i;ans%=mod; }
        ans=ans*n%mod;
        ll k=1;
        For(i,1,m) { k=k*i%mod; }
        ll x=qpow(k,mod-2);
        ans=ans*x%mod;
        if(((n-m)/2)&1) ans=(mod-ans)%mod;
        cout<<ans<<endl;
    }

#ifdef MengLan
    printf("Time: %d\n",clock()-Beginning);
#endif // MengLan
    return 0;
}
1

 

以上是关于2017 ACM-ICPC 亚洲区(西安赛区)网络赛的主要内容,如果未能解决你的问题,请参考以下文章

2017 ACM-ICPC 亚洲区(西安赛区)网络赛: B. Coin 概率题

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 G. Xor

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B.Coin(基本概率+二项式展开)

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 F.Trig Function(论文+组合数)

2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B题 Coin 题解

017 ACM-ICPC 亚洲区(西安赛区)网络赛 Coin 概率+矩阵快速幂