2019 ICPC 南昌 部分题解

C - And and Pair

题意不说了。简单说下想法
对于每一位二进制位,如果 s[i]1,那么为了满足 i\&n=i ,可以放10 有两种放法。对于放 1 时候,为了满足 i\&j=0j 只能放 0 ,对于放 0 的时候,j 能放 10 。所以当 s[i]1 时,其对之后的位数贡献为 3
同理,当 s[i]0 时,其贡献为 2
这里有个小细节,就是当前 S 全为 0 时,也就是说 n0,那么这个时候,i 只能取 0j 可以取 10,但是又要满足 n >= j,所以当在这种情况下,只有一种取法,这种取法也是之前推导贡献情况没有考虑到的,所以最后答案要加 1
也可以开数组预处理幂次,我这里直接快速幂了,时间复杂度 O(N)
代码如下

#include <iostream>
#include <cstdio>
#include <ctime>
#include <stack>
#include <queue>
#include <map>
#include <cstring>
#include <cstdlib>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <bitset>
#define endl '\n'
#define int long long
#define INF 2147483647
using namespace std;
const int MOD = 1e9+7;
int Max(int a,int b){return a>b?a:b;}
int Min(int a,int b){return a<b?a:b;}
int QPow(int a,int b){int res=1;while(b){if(b&1){res=(res*a)%MOD;}b>>=1;a=(a*a)%MOD;}return res%MOD;}
int Inv(int a,int Mod){return QPow(a,Mod-2);}
int t;
string s;
int ans;
signed main(void){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> t;
    while(t--){
        cin >> s;
        ans = 0;
        int cnt1 = 0;
        int cnt0 = 0;
        for(int i=s.length()-1;i>=0;i--){
            if(s[i]=='1') {
                ans += 1LL*QPow(2,cnt0)*QPow(3,cnt1);
                ans %= MOD;
            }
            if(s[i]=='1'){
                cnt1++;
            }else{
                cnt0++;
            }
        }
        ans++;
        ans %=MOD;
        cout << ans << endl;
    }
    return 0;
}

K - Tree

树上启发式合并。
我们要找的是什么?找的是点对。我们枚举每个 LCA
那么我们是否可以这么考虑,先将第一个孩子的点及其子树的点全部放入桶种(即记录下来),然后其他子树的孩子每次被遍历到一个点就查询在桶种有多少个符合答案的点对。
我们用 (u_x,u_d) 来表示某个点的权值以及深度。那么对于这个点,能和其组成一对,且满足条件的点对需满足如下式子
(v_x = 2LCA_x-u_x,v_d <= 2LCA_d+k-u_d)。暴力求法是O(N)的,因为要枚举每个点对。
要将其优化为 O(logN) ,在这里,我们可以用平衡树或者权值线段树(动态开点)来做。权值线段树维护深度为[l,r] 范围内权值为 p 的点有多少个。需要注意的是整棵树的最大深度为 n,即退化为链。所以还需要满足以下条件
v_d <= n
总时间复杂度O(N(logN)^2)
代码如下:

#include <iostream>
#include <cstdio>
#include <ctime>
#include <stack>
#include <queue>
#include <map>
#include <cstring>
#include <cstdlib>
#include <set>
#include <string>
#include <vector>
#include <algorithm>
#include <bitset>
#define endl '\n'
#define int long long
#define INF 2147483647
#define MOD 19260817
using namespace std;
int Max(int a,int b){return a>b?a:b;}
int Min(int a,int b){return a<b?a:b;}
int QPow(int a,int b){int res=1;while(b){if(b&1){res=(res*a)%MOD;}b>>=1;a=(a*a)%MOD;}return res%MOD;}
int Inv(int a,int Mod){return QPow(a,Mod-2);}
const int MAXN = 1e5+10;
// struct Edge{
//     int v,next;
// }e[MAXN*2];
vector<int> E[MAXN];
int ecnt;int head[MAXN];
int res;
int root[MAXN],ls[MAXN*100],rs[MAXN*100],num[MAXN*100],cnt;
void update(int &p,int l,int r,int x,int v){
    if(!p) p = ++cnt;
    num[p] += v;
    if(l==r) return;
    int mid = (l+r)>>1;
    if(x<=mid) update(ls[p],l,mid,x,v);
    else update(rs[p],mid+1,r,x,v);
}
int ask(int p,int l,int r,int ql,int qr){
    if(!p) return 0;
    if(ql > qr) return 0;
    if(ql <= l && qr >= r){
        return num[p];
    }
    int ans = 0;
    int mid = (l+r)>>1;
    if(ql <= mid){
        ans += ask(ls[p],l,mid,ql,qr);
    }
    if(qr > mid){
        ans += ask(rs[p],mid+1,r,ql,qr);
    }
    return ans;
}
int n,k,w[MAXN],fa[MAXN];
int dep[MAXN];
int siz[MAXN];
int st[MAXN],ed[MAXN],dfn[MAXN],tot;
void dfs(int u){
    siz[u] = 1;
    st[u] = ++tot;
    dfn[tot] = u;
    for(int v:E[u]){
        if(v != fa[u]){
            dep[v] = dep[u] + 1;
            dfs(v);
            siz[u] += siz[v];
        }
    }
    ed[u] = tot;
}
void dfs(int u,bool keep){
    int mx = -1;
    int son = -1;
    for(int v:E[u]){
        if(v != fa[u] && siz[v] > mx){
            mx = siz[v];
            son = v;
        }
    }
    for(int v:E[u]){
        if(v != fa[u] && v != son){
            dfs(v,0);
        }
    }
    if(son != -1){
        dfs(son,1);
    }
    for(int v:E[u]){
        if(v != fa[u] && v != son){
            for(int i = st[v];i <= ed[v];i++){
                int x = dfn[i];
                int need = 2*w[u]-w[x];
                if(need >= 0 && need <= n){
                    res+=ask(root[need],1,n,dep[u]+1,Min(n,2*dep[u]+k-dep[x]));
                }
            }
            for(int i=st[v];i <= ed[v];i++){
                int x = dfn[i];
                update(root[w[x]],1,n,dep[x],1);
            }
        }
    }
    update(root[w[u]],1,n,dep[u],1);
    if(!keep){
        for(int i=st[u];i <= ed[u];i++){
            int x = dfn[i];
            update(root[w[x]],1,n,dep[x],-1);
        }
    }
}
signed main(void){
    // cin >> n >> k;
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%lld",w+i);
        // cin >> w[i];
    }
    for(int i=2;i<=n;i++){
        scanf("%lld",fa+i);
        // cin >> fa[i];
        E[fa[i]].push_back(i);
    }
    dfs(1);
    dfs(1,0);
    printf("%lld",2LL*res);
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

  • [TOC] 贪心 AcWing122.糖果传递[1][#fn1] 有n个小朋友坐成一圈,每人有a[i]个糖果。每人...
    北以凝阅读 474评论 1 1
  • 这个月内的一些有趣的题 Letter Array http://codeforces.com/gym/100482...
    TimeMage阅读 447评论 0 1
  • K - Russian Dolls on the Christmas Tree[https://vjudge.ne...
    alyjay阅读 369评论 0 0
  • 区间 是什么 关于动态规划,其实说白了,就是一种递推。当我们解决大问题的时候,先把它 分解 为若干个子问题,再把...
    BreakPlus阅读 1,303评论 0 3
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 6,050评论 0 4