保存子樹某個數出現的次數然后從葉子節點向上更新合并合并的時候需要size小的向size大的上面合并這樣省時這是由map的構造決定的用c++提交要手動開棧否則會棧溢出用G++提交可以避免但花費時間要長一些自測數據對我來說很重" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

hdu 4358 Boring counting

系統 1949 0

http://acm.hdu.edu.cn/showproblem.php?pid=4358

map 版本 ?

比賽的時候也用map 寫了 不過沒有加優化 所以超時了

調試了一上午 ?下午自己出數據測了一下才知道那里出錯了 汗

大體思路:

用map<int , int > 保存子樹某個數出現的次數 然后從葉子節點向上更新合并 合并的時候需要 size小的向size大

的上面合并 這樣省時 這是由map 的構造決定的

用c++ 提交要 手動開棧 ?否則會棧溢出 ?用G++ 提交可以避免但花費時間要長一些

自測數據 對我來說很重要的一組數據 就是這里錯了一上午

1
6 1
1 2 3 4 5 6
1 2
1 3
3 4
3 5
1 6
6
1
2
3
4
5
6

詳情及其細節見代碼及其注釋:

      #include<iostream>

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<map>

#include<queue>

#include<cmath>

#define LL long long

//#pragma comment(linker, "/STACK:102400000,102400000")//c++提交的話 需要手動開棧(看解析上的) g++不用 但時間花費長



using namespace std;



const int N=100005;

int head[N];//鄰接表 表頭

struct node

{

    int j;

    int next;

}side[N*2];

int son[N];//兒子節點個數

int f[N];//保存父節點

int id[N];//某個節點對應相關數據存在了哪個map里面 由于合并的關系 剛開始 i和id[i]對應相等 但一定的合并后就變了

int ans[N];//保存答案 離線保存要用

map<int ,int>str[N];

map<int ,int>:: iterator it,it1;

queue<int>qu;

int K;

void build(int x,int i)

{

    side[i].next=head[x];

    head[x]=i;

}

void dfs(int x,int pre)//用dfs求的本節點的父節點 和兒子節點數  和將葉子節點加入隊列

{

    int t=head[x];

    f[x]=pre;

    while(t!=-1)

    {

        if(side[t].j!=pre)

        {

          dfs(side[t].j,x);

          ++son[x];

        }

        t=side[t].next;

    }

    if(son[x]==0)

    {

        qu.push(x);

    }

}

void Add(int I,int i,int j)//將 map j 合并到i當中 將答案ans[I]進行更新

{

    for(it=str[j].begin();it!=str[j].end();++it)//it 遍歷map j 的元素

    {

        it1=str[i].find(it->first);//到i 中查詢

        if(it1==str[i].end())//未找到

        {

            str[i][it->first]=it->second;//加入

            if(it->second==K)//如果正好等于K 則答案加一

            ++(ans[I]);

            continue;

        }

        if(it1->second==K)//如果找到 本來在i中 這個數出現次數正好為K 在加上一個非0數則不等于K 了所以答案個數減1

        --(ans[I]);

        if((it1->second+=it->second)==K)//如果加上正好為K 答案個數加1 這不會和上一個沖突

        ++(ans[I]);

    }

}

int main()

{

    //freopen("data.txt","r",stdin);

    int T;

    scanf("%d",&T);

    for(int cas=1;cas<=T;++cas)

    {

        memset(head,-1,sizeof(head));

        memset(ans,0,sizeof(ans));

        memset(son,0,sizeof(son));//各種初始化

        while(!qu.empty())

        qu.pop();

        int n,q;

        scanf("%d %d",&n,&K);

        for(int i=1;i<=n;++i)

        {

            int a;

            str[i].clear();//清空

            id[i]=i;//本來每個節點 的map 就是自己對應的

            scanf("%d",&a);

            str[i][a]=1;//先都加入 本節點的數

            if(K==1)//如果K正好為1 則答案也更新

            ++ans[i];

        }

        int x,y;

        for(int i=1;i<n;++i)//輸入邊 建樹

        {

            scanf("%d %d",&x,&y);

            side[i].j=y;

            build(x,i);

            side[i+n].j=x;

            build(y,i+n);/

        }

        dfs(1,0);//搜一個

        while(!qu.empty())

        {

            int l=qu.front();//取元素

            if(l==1)

            break;//如果到了1 則全求出 可以停止

            qu.pop();

            int fa=f[l];//fa為父親節點

            --son[fa];//父親節點的可以更新的兒子節點減少1

            if(son[fa]==0)//這是最后一個兒子節點 這是將fa加入隊列 千萬不能第一次更新就加入 

            {//否則會出現父節點在兒子節點前面的情況 就錯了(自己輸在這里了)  見上面數據

                qu.push(fa);

            }

            int li=id[l];//找到對應的map 

            int fai=id[fa];

            if(str[fai].size()>str[li].size())//比較大小

            {

                Add(fa,fai,li);

            }else

            {

                ans[fa]=ans[l];//如果需要往l上合并 則先等于l的ans 在下面更新后ans[fa] 始終保存當前對應map里面的答案

                id[fa]=li;//更改對應的map

                Add(fa,li,fai);//更新

            }

        }

        scanf("%d",&q);

        printf("Case #%d:\n",cas);

        while(q--)

        {

            scanf("%d",&x);

            printf("%d\n",ans[x]);

        }

        if(cas<T)

        printf("\n");

    }



    return 0;

}


    

hdu 4358 Boring counting


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 午夜在线观看免费视频 | 久久精品一区二区 | 欧美日视频 | 久久久久久久av | 欧洲精品视频在线观看 | 欧美一区二区三区不卡免费 | 免费中日高清无专码有限公司 | 亚洲成人黄色在线 | 最近最新中文字幕 | 亚洲 欧美 日韩 在线 | 在线观看亚洲专区 | 2020国产精品视频免费 | 一级国产黄色片 | 亚洲精品456人成在线 | 国产精品福利视频手机免费观看 | 欧美一级美国一级 | 狠狠色丁香婷婷综合久久片 | 色人阁亚洲 | 美腿丝袜亚洲综合 | 欧美在线一级片 | 极色品影院 | 久色视频在线观看 | 五月天婷婷免费观看视频在线 | 欧美日韩国产在线观看 | 欧美一级免费 | 美女用震蛋叫爽的视频95视频 | 精品区在线观看 | 国产精品久久久久久久久久免费看 | 182tv在线观看国产路线一 | 五月天婷婷缴情五月免费观看 | xifan在线a精品一区二区视频网站 | 91免费视频网站 | 欧美精品国产一区二区三区 | 日日摸夜夜摸狠狠摸日日碰夜夜做 | 国产色司机在线视频免费观看 | 欧美日韩在线一区二区 | 国产五月色婷婷六月丁香视频 | 色综合久久伊人 | 久久亚| 青青青青娱乐 | 中文二区 |