78-76: 模拟赛

$sol$

暴力判断,枚举和的约数判断

注意 0 的特判

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

#define YES puts("YES")
#define NO puts("NO")

char s[N];
int Len;

bool See(int x) {
    int tot = 0;
    for(int i = 1; i <= Len; i ++) {
        if(s[i] - '0' > x) return 0;
        tot += s[i] - '0';
        if(tot % x == 0) tot = 0;
        if(tot > x) return 0;
    }
    return 1;
}

int main() {
    int t; cin >> t;
    while(t --) {
        scanf("%s", s + 1);
        Len = strlen(s + 1);
        int sum = 0;
        int Min = (1 << 30);
        for(int i = 1; i <= Len; i ++) sum += s[i] - '0', Min = min(Min, s[i] - '0');
        if(sum == 0) {
            YES; continue;
        } 
        bool flag = 1;
        for(int i = Min + 1; i < sum; i ++) {
            if(sum % i) continue;
            if(See(i)) {
                YES; flag = 0;
                break;
            }
        }
        if(flag) NO;
    }
    return 0;
}

这这这,这什么

$sol$

$f_u$ 表示以 $u$ 为根的子树中被覆盖的点的点权和最大为多少
若点 $u$ 不被覆盖则 $f_u = \sum f_v$,v 是点 u 的儿子结点
若 u 被路径 $(x, y)$ 覆盖,且 $u$ 是 $x$ 和 $y$ 的最近公共祖先
$f_u = \sum a_v$, v 在路径(x, y) 上 + $\sum f_v$, v 不在路径(x,y)上,v的父亲在路径(x,y)上
用线段树维护每个点到根结点的信息,或者树链剖分维护路径上的信息
时间复杂 O(nlogn)

$code$

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pr;
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define Rep(i,u) for(int i=head[u];i;i=Next[i])
ll read() {
    ll ans=0;
    char last=' ',ch=getchar();
    while(ch<'0' || ch>'9')last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans;
    return ans;
}
//head
#define N 210000
int head[N],v[N],Next[N],dep[N],fa[N][18],a[N],st[N],ed[N];
int n,num,m,num2,num3,nn,head2[N],v2[N],Next2[N];
int lson[N],rson[N],root=0;
ll Sum,f[N],s[N][2],sa[N];
struct node {
    int x,y,z;
} q[N];
void add(int x,int y) {
    v[++num]=y;
    Next[num]=head[x];
    head[x]=num;
}
void add2(int x,int y) {
    v2[++num2]=y;
    Next2[num2]=head2[x];
    head2[x]=num2;
}
int Q[N],siz[N];
void dfs(int u) {
    int t=0,w=1;
    Q[1]=u;
    while(t<w) {
        u=Q[++t];
        sa[u]=sa[fa[u][0]]+a[u];
        for(int i=1; (1<<i)<=dep[u]; i++)
            fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=head[u]; i; i=Next[i])
            if(v[i]!=fa[u][0]) {
                fa[v[i]][0]=u;
                dep[v[i]]=dep[u]+1;
                Q[++w]=v[i];
            }
        siz[u]=1;
    }
    per(i,w,2)siz[fa[Q[i]][0]]+=siz[Q[i]];
    st[1]=1;
    rep(i,1,n) {
        u=Q[i];
        int t=st[u];
        ed[u]=st[u]+siz[u]-1;
        for(int i=head[u]; i; i=Next[i])
            if(v[i]!=fa[u][0])st[v[i]]=t+1,t+=siz[v[i]];
    }
}
int lca(int x,int y) {
    if(dep[x]<dep[y])swap(x,y);
    per(i,17,0)
    if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];
    if(x==y)return x;
    per(i,17,0)
    if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    return fa[x][0];
}
int lca2(int x,int y) {
    per(i,17,0)
    if(dep[x]-(1<<i)>dep[y])x=fa[x][i];
    return x;
}
void change(int &u,int l,int r,int x,int y,ll w,int k) {
    if(x>r || y<l)return ;
    if(!u)u=++num3;
    if(x<=l && y>=r) {
        s[u][k]+=w;
        return;
    }
    int mid=(l+r)>>1;
    change(lson[u],l,mid,x,y,w,k);
    change(rson[u],mid+1,r,x,y,w,k);
}
ll find(int u,int l,int r,int x,int k) {
    if(!x)return 0;
    if(!u)return 0;
    if(l==r)return s[u][k];
    int mid=(l+r)>>1;
    if(x<=mid)return find(lson[u],l,mid,x,k)+s[u][k];
    else return find(rson[u],mid+1,r,x,k)+s[u][k];
}
ll work2(int x,int y) {
    return find(root,1,n,st[x],1)-find(root,1,n,st[fa[y][0]],1)-(find(root,1,n,st[x],0)-find(root,1,n,st[y],0));
}
ll work(int x,int y,int z) {
    if(dep[x]<dep[y])swap(x,y);
    if(y==z)return work2(x,y)+sa[x]-sa[fa[y][0]];
    int t=lca2(y,z);
    return work2(x,z)+work2(y,t)-f[t]+sa[x]+sa[y]-sa[z]-sa[fa[z][0]];
}
void dfs2(int u) {
    per(i,n,1) {
        u=Q[i];
        f[u]=0;
        for(int i=head[u]; i; i=Next[i])
            if(v[i]!=fa[u][0])f[u]+=f[v[i]];
        for(int i=head2[u]; i; i=Next2[i]) {
            int t=v2[i];
            int x=q[t].x,y=q[t].y,z=q[t].z;
            f[u]=max(f[u],work(x,y,z));
        }
        change(root,1,n,st[u],ed[u],f[u],0);
        change(root,1,n,st[fa[u][0]],ed[fa[u][0]],f[u],1);
    }
}
int main() {
    n=read();
    rep(i,1,n)a[i]=read();
    rep(i,2,n) {
        int x=read(),y=read();
        add(x,y);
        add(y,x);
    }
    dfs(1);
    m=read();
    rep(i,1,m)q[i].x=read(),q[i].y=read(),q[i].z=lca(q[i].x,q[i].y),add2(q[i].z,i);
    dfs2(1);
    cout<<f[1]<<endl;
    return 0;
}

 感觉不可做

想了较长时间T3,做了无用功

posted @ 2018-10-29 19:54  xayata  阅读(143)  评论(0编辑  收藏  举报