bestcoder #82 div2

可能是最后的一场bestcoder,没上div1确实是有点遗憾,,,这场题目比较简单,认真打的话AK应该问题不大。

01: 

判断n=x^2-y^2是否有正整数解。由于上场codeforces中毒了,这次一看01直接懵了。。。不会。。。赛后一想,,,果然水题。。。。

n=(x+y)*(x-y) , 令p=x+y,q=x-y, 则 x=(p+q)/2,y=(p-q)/2, 那么p,q必然同奇偶,从而n应该是>=3的奇数或>=6的4的倍数。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

ll n;

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%I64d",&n);
        puts(n!=1&&n!=4&&(n%4==0||n%2)?"True":"False");
    }
    return 0;
}
View Code

02: 

由于中毒颇深,大脑死机了,加上环境比较吵,而且还在吃饭。。。所以。。。。

其实这题很水的。。。直接预处理出所有的数,然后二分找答案即可。。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<set>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;

ll n;
set<ll> ans;

void dfs(int n,int a,int b,ll num)
{
    //cout<<"n="<<n<<" a="<<a<<" b="<<b<<" num="<<num<<endl;
    if(n==0){
        if(num&&a==b) ans.insert(num);
        return;
    }
    if(a+n<b||b+n<a) return;
    dfs(n-1,a+1,b,num*10+4);
    dfs(n-1,a,b+1,num*10+7);
}

void Init()
{
    ans.clear();
    REP(i,1,18) dfs(i,0,0,0);
}

void solve()
{
    set<ll>::iterator it=ans.lower_bound(n);
    if(it==ans.end()) puts("44444444447777777777");
    else printf("%I64d
",*it);
}

int main()
{
    //freopen("in.txt","r",stdin);
    Init();
    int T;cin>>T;
    while(T--){
        scanf("%I64d",&n);
        solve();
    }
    return 0;
}
View Code

03:

水题。。。当时一样就看出思路了。。。。就是回文树预处理出所有长度为i的回文串的个数,然后跑背包。。。

吐槽下数据。。。我在第10分钟左右看题,第30分钟时交了第一发没过,第40分钟交了第二发,这个应该是AC的,比赛的时候给判WA了。。。导致我去改边界,再WA了几发之后终于在第59分钟过了。。。赛后才听是标程边界没处理好。。。bc就是坑。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=210;
const int INF=1e9+10;

int Nn;
int c[maxn];
struct PalinTree
{
    int ch[maxn][26],f[maxn];
    int cnt[maxn],num[maxn],len[maxn];
    int s[maxn];
    int last,n,tot;
    int newnode(int l)
    {
        MS0(ch[tot]);
        cnt[tot]=0;
        num[tot]=0;
        len[tot]=l;
        return tot++;
    }
    void init()
    {
        tot=0;
        newnode(0);
        newnode(-1);
        last=0;n=0;
        s[n]=-1;f[0]=1;
    }
    int get_fail(int x)
    {
        while(s[n-len[x]-1]!=s[n]) x=f[x];
        return x;
    }
    void add(int c)
    {
        c-='a';
        s[++n]=c;
        last=get_fail(last);
        if(!ch[last][c]){
            int cur=newnode(len[last]+2);
            f[cur]=ch[get_fail(f[last])][c];
            ch[last][c]=cur;
            num[cur]=num[f[cur]]+1;
        }
        last=ch[last][c];
        cnt[last]++;
    }
    void count()
    {
        for(int i=tot-1;i>=0;i--) cnt[f[i]]+=cnt[i];
    }
    void dfs(int u)
    {
        if(u!=0&&u!=1){
            c[len[u]]+=cnt[u];
        }
        REP(i,0,25) if(ch[u][i]) dfs(ch[u][i]);
    }
};PalinTree pt[maxn];
int dp[maxn][maxn][maxn];
int N,K,L;
char s[maxn][maxn];int ls[maxn];

void solve()
{
    MS0(dp);
    dp[0][0][0]=1;
    REP(i,1,Nn){
        REP(j,0,K){
            REP(k,0,L){
                REP(x,0,c[i]){
                    if(j>=x&&k>=x*i) dp[i][j][k]|=dp[i-1][j-x][k-x*i];
                }
            }
        }
    }
    puts(dp[Nn][K][L]?"True":"False");
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d%d%d",&N,&K,&L);
        Nn=110;
        MS0(c);
        REP(i,1,N){
            scanf("%s",s[i]);
            ls[i]=strlen(s[i]);
            pt[i].init();
            REP(j,0,ls[i]-1) pt[i].add(s[i][j]);
            pt[i].count();
            pt[i].dfs(0);
            pt[i].dfs(1);
        }
        solve();
    }
    return 0;
}
View Code

04:

这种题已经烂大街了。。。直接对树进行一次dfs遍历,然后对dfs序列求区间第k大,,,主席树或者树套树都可以。。。然后由于n为1e5,m为1e6,所以预处理n个答案,最后o(1)回答m次询问会更好。。。卡常数卡得如此丧心病狂。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define MS0(a) memset(a,0,sizeof(a))

using namespace std;

typedef long long ll;
const int maxn=1000100;
const int INF=1e9+10;
const ll MOD=1e9+7;

int n,m;
int val[maxn];
vector<int> G[maxn];
int u,v;
double ans[maxn];
int id[maxn],fid[maxn];
int cnt[maxn];
int b[maxn],bn;
struct Node
{
    int l,r;
    int ls,rs;
    int sum;
};Node tr[maxn*64];
int rt[maxn],tot;
int idn;

int dfs(int u)
{
    ++idn;
    id[u]=idn;
    fid[idn]=u;
    int res=1;
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        cnt[v]=dfs(v);
        res+=cnt[v];
    }
    return res;
}

void push_up(int rt)
{
    tr[rt].sum=0;
    if(~tr[rt].ls) tr[rt].sum+=tr[tr[rt].ls].sum;
    if(~tr[rt].rs) tr[rt].sum+=tr[tr[rt].rs].sum;
}

int build(int l,int r)
{
    int k=++tot;
    tr[k]=(Node){l,r,-1,-1,0};
    if(l==r) return tot;
    int m=(l+r)>>1;
    tr[k].ls=build(l,m);
    tr[k].rs=build(m+1,r);
    push_up(k);
    return k;
}

int update(int p,int c,int rt)
{
    int k=++tot;
    tr[k]=tr[rt];
    int l=tr[rt].l,r=tr[rt].r;
    if(l==r){
        tr[k].sum+=c;
        return k;
    }
    int m=(l+r)>>1;
    if(p<=m) tr[k].ls=update(p,c,tr[k].ls);
    else tr[k].rs=update(p,c,tr[k].rs);
    push_up(k);
    return k;
}

int query(int k,int s,int t)
{
    if(tr[s].l==tr[s].r) return tr[s].l;
    int cnt=tr[tr[s].ls].sum-tr[tr[t].ls].sum;
    if(k<=cnt) return query(k,tr[s].ls,tr[t].ls);
    else return query(k-cnt,tr[s].rs,tr[t].rs);
}

void Init()
{
    tot=0;
    rt[0]=build(1,bn);
    REP(i,1,n) rt[i]=update(val[fid[i]],1,rt[i-1]);
    int L,R,x,y;
    REP(i,1,n){
        L=id[i];R=id[i]+cnt[i]-1;
        if(cnt[i]&1){
            x=query(cnt[i]/2+1,rt[R],rt[L-1]);
            ans[i]=1.0*b[x];
        }
        else{
            x=query(cnt[i]/2,rt[R],rt[L-1]);
            y=query(cnt[i]/2+1,rt[R],rt[L-1]);
            ans[i]=1.0*(1LL*b[x]+b[y])/2;
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    int T;cin>>T;
    while(T--){
        scanf("%d%d",&n,&m);
        REP(i,1,n) G[i].clear();
        REP(i,1,n) scanf("%d",&val[i]);
        bn=0;
        REP(i,1,n) b[++bn]=val[i];
        sort(b+1,b+bn+1);
        bn=unique(b+1,b+bn+1)-(b+1);
        REP(i,1,n) val[i]=lower_bound(b+1,b+bn+1,val[i])-b;
        REP(i,1,n-1){
            scanf("%d%d",&u,&v);
            G[u].push_back(v);
        }
        idn=0;
        cnt[1]=dfs(1);
        Init();
        double res=0;
        REP(i,1,m){
            scanf("%d",&u);
            res=fmod(res*10+ans[u],MOD*1.0);

        }
        printf("%.1f
",res);
    }
    return 0;
}
View Code
没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/5453042.html