contest20151130

jsoi2015 round2 day1
呵呵

T1

傻逼结论题?

ans=2nk

其实呢,这题题解本来是不用写的。那么为什么要写呢?因为窝学习了 latex ,特意来试试。就是上面的ans=2^(nk),效果不错吧

T2

考的时候果断 n2 暴力怒骗20分。
那么做法呢
分数规划是什么窝怎么听不懂
二分答案,设二分值为b

M(i,j)m(i,j)ji+k>b

显然当 l< 长度 <r <script type="math/tex" id="MathJax-Element-5"> l r可以 O(nlogn) 做嘛。。
a[i]a[j]>bjbi+bk a[j]a[i]>bjbi+bk
那么
(a[i]+bi)(a[j]+bj)>bk (a[i]+bi)(a[j]+bj)>bk
然后就单调队列辣(%NiroBC大神犇)
“若后放进的比先放进的优,把先放进的去掉”

T3

可持久化Trie树吧。。听说hash能过(出题人的锅!)
然而窝刚刚会可持久(然后就A了)

Codes

T1

#include<bits/stdc++.h>
using namespace std;
#define SC scanf
#define U_(i,a,b) for(int i=a;i<=b;i++)
#define D_(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
#define MK make_pair
#define A first
#define B second
const ll mod=1000000007;
ll n,k;
ll power(ll a,ll b){
    ll re=1;
    while(b){
        if(b&1)re=re*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return re;
}
int main(){
    SC("%lld%lld",&n,&k);
    printf("%lld\n",power(2,n*k));
}

T2

#include<bits/stdc++.h>
using namespace std;
#define SC scanf
typedef long long ll;
#define U_(i,a,b) for(ll i=a;i<=b;i++)
#define D_(i,a,b) for(ll i=a;i>=b;i--)
const ll N=50010;
double a[N],e[N],c[N][20],d[N][20];
ll q[N<<1];
ll n,l1,r1,lg,Log[2000000],mi[30];
double k;
void build(){U_(i,1,lg)U_(j,1,n-mi[i]+1)c[j][i]=min(c[j][i-1],c[j+mi[i-1]][i-1]);}
void Build(){U_(i,1,lg)U_(j,1,n-mi[i]+1)d[j][i]=max(d[j][i-1],d[j+mi[i-1]][i-1]);}
double query(ll l,ll r){ll t=Log[r-l+1];return min(c[l][t],c[r-mi[t]+1][t]);}
double Query(ll l,ll r){ll t=Log[r-l+1];return max(d[l][t],d[r-mi[t]+1][t]);}
bool check(double b){
    U_(i,1,n)e[i]=a[i]+b*i;
    ll H=1,T=1;
    q[1]=n;
    D_(i,n-l1+1,1){
        while(H<=T && q[H]>i+r1-1)H++;
        if(e[i]-e[q[H]]>=b*k)return 1;
        while(H<=T && e[q[T]]>=e[i+l1-2])T--;
        q[++T]=i+l1-2;
    }
    U_(i,1,n)e[i]=-a[i]+b*i;
    H=1,T=1;
    q[1]=n;
    D_(i,n-l1+1,1){
        while(H<=T && q[H]>i+r1-1)H++;
        if(e[i]-e[q[H]]>=b*k)return 1;
        while(H<=T && e[q[T]]>=e[i+l1-2])T--;
        q[++T]=i+l1-2;
    }
    return 0;
}
int main(){
    ll T;
    SC("%lld",&T);
    mi[0]=1;
    U_(i,1,20)mi[i]=mi[i-1]*2;
    U_(i,0,19)U_(j,mi[i],mi[i+1]-1)Log[j]=i;
    while(T--){
        SC("%lld%lf%lld%lld",&n,&k,&l1,&r1);
        U_(i,1,n)SC("%lf",&a[i]);
        double L=0,R=1000;
        U_(i,1,n)c[i][0]=d[i][0]=a[i];
        lg=Log[r1];
        build();Build();
        U_(i,1,n-l1+1)L=max(L,(Query(i,i+l1-1)-query(i,i+l1-1))/(l1-1+k));
        U_(i,1,n-r1+1)L=max(L,(Query(i,i+r1-1)-query(i,i+r1-1))/(r1-1+k));
        l1++,r1--;
        if(l1<=r1){
            while(R-L>0.000001){
                double mid=(L+R)/2;
                if(check(mid))L=mid;else R=mid;
            }
        }
        printf("%.4lf\n",L);
    }
}

T3

#include<bits/stdc++.h>
using namespace std;
#define SC scanf
#define U_(i,a,b) for(int i=a;i<=b;i++)
#define D_(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
#define MK make_pair
#define A first
#define B second
#define lc rt<<1
#define rc rt<<1|1
const int N=101000;
char s[11];
struct EG{int a,b;char c[11];}eg[N<<1];
struct Node{int nxt[26],sum;}T[N*20];
int en,head[N],fa[N][20],rot[N],cnt,dep[N],n,q;
void add(int u,int v){
    eg[++en].a=v;
    eg[en].b=head[u];
    U_(i,0,10)eg[en].c[i]=s[i];
    head[u]=en;
}
void dfs(int u){
    for(int e=head[u];e;e=eg[e].b){
        int v=eg[e].a;
        if(v==fa[u][0])continue;
        fa[v][0]=u;
        dep[v]=dep[u]+1;
        dfs(v);
    }
}
void up(int &u,int s){
    int i=0;
    while(s){
        if(s&1)u=fa[u][i];
        i++;
        s>>=1;
    }
}
int lca(int u,int v){
    if(dep[u]>dep[v])swap(u,v);
    up(v,dep[v]-dep[u]);
    if(u==v)return u;
    D_(i,18,0)
        if(fa[u][i]!=fa[v][i]){
            u=fa[u][i];
            v=fa[v][i];
        }
    return fa[u][0];
}
void ins(int &i,char*s){
    T[++cnt]=T[i];i=cnt;T[i].sum++;
    if(*s)ins(T[i].nxt[(*s)-'a'],s+1);
}
void DFS(int u){
    for(int e=head[u];e;e=eg[e].b){
        int v=eg[e].a;
        if(v==fa[u][0])continue;
        rot[v]=rot[u];
        ins(rot[v],eg[e].c);
        DFS(v);
    }
}
int query(int a,int b,int c,char*s){
    if(!(*s))return T[a].sum+T[b].sum-T[c].sum*2;
    return query(T[a].nxt[(*s)-'a'],T[b].nxt[(*s)-'a'],T[c].nxt[(*s)-'a'],s+1);
}
int main(){
    SC("%d",&n);
    U_(i,1,n-1){
        int u,v;
        SC("%d%d%s",&u,&v,s);
        add(u,v);
        add(v,u);
    }
    fa[1][0]=1;
    dfs(1);
    U_(i,1,18)U_(j,1,n)fa[j][i]=fa[fa[j][i-1]][i-1];
    DFS(1);
    SC("%d",&q);
    while(q--){
        int u,v;
        SC("%d%d%s",&u,&v,s);
        int t=lca(u,v);
        printf("%d\n",query(rot[u],rot[v],rot[t],s));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值