hihoCoder挑战赛4 光棍节

题目3 : 光棍节

时间限制:30000ms

单点时限:1000ms

内存限制:256MB

描述

尽管付出了种种努力,jzp还是得过光棍节。

jzp非常不爽,但也无能为力,只能够哀叹起来他的命运。他想到了一位长者的人生经验:“人的一生,不光要靠自我奋斗,也要考虑历史的进程”。

他终于明白自己只是时运不济,所以又继续开始努力。终于在圣诞节当天把到了妹子。

jzp从此过上了快乐的现充生活,在圣诞节当天,他还和妹子玩起了有趣的游戏:

jzp的家里有一棵非常大的圣诞树,可以看成是一个n个点的无向联通无环图。每个点上都有一个正整数,JZP和妹子每次都会选择树上的一条路径,

这条路径的权值被定义为路径上所有点上数的最大公约数,JZP可以得到这个权值的分数。

JZP玩了一会儿有点腻了,他想知道对于每种可能的权值x,权值为x的不同路径的数量(a到b的路径和b到a的路径算作一种,a到a自身也算作一条路径。)

输入

第一行一个整数n(1<=n<=105)表示圣诞树的大小,点从1开始标号。

接下来一行n个整数用单个空格隔开,第i个表示第i个点上的数。(数都在1到105之间)。

接下来n-1行,每行两个数a和b,表示a和b之间有一条边。

输出

令C(x)表示权值为x的路径的个数。

从小到大输出对于所有C(x)>0的x,输出一行两个数x和C(x),用空格隔开。

样例输入
20
2 4 2 4 2 4 2 20 20 12 12 12 2 12 2 4 4 2 12 2
1 2
1 3
1 4
2 5
3 6
1 7
6 8
2 9
6 10
5 11
4 12
11 13
10 14
3 15
9 16
7 17
4 18
4 19
16 20
样例输出
2 186
4 16
12 6
20 2

思路:一看就是树分治的题,可是想想都会T 啊,可是实在没事可以做,所以只有去暴力了,加了一些优化,     交了wa,改了改,还是wa 。。。。 后面把优化全部去掉,终于T了,好像很兴奋的样子     后面看了代码,发现一个地方错了,可是只有几分钟了。。。。     改了交,然后有把优化加上,又交了一发。     然后结束了,心里想又挂0 了。。。     后面没加优化的过了。。。。。==     最后一分钟过的。。不容易呀

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<map>
#include<ctime>
#include<bitset>
#define LL long long
#define ll long long
#define INF 0x3f3f3f3f
#define maxn 200010
#define eps 1e-6
#define mod 1000000007
using namespace std;

int head[maxn] , to[maxn*2] ,next1[maxn*2] ;
int top ,cnt[maxn] , f[maxn];
int  k ,ans ,n ;
vector<int>vec;
bool vi[maxn] ;

void Unit(int x,int y)
{
    to[top]=y;next1[top]=head[x] ;
    head[x]=top++;
}
void find1( int u ,int fa )
{
    f[u] = 0 ;
    cnt[u] = 1 ;
    int v ;
    for( int i = head[u] ; i != -1; i = next1[i])
    {
         v = to[i] ;
        if(v==fa||vi[v]) continue ;
        find1(v,u) ;
        cnt[u] += cnt[v] ;
        f[u] = max(cnt[v],f[u]) ;
    }
}
int minn ;
void find_root1( int u ,int fa,int &root,int sum)
{
    int tmp = max(sum-cnt[u],f[u]) ;
    if(tmp < minn)
    {
        minn = tmp ;
        root = u ;
    }
    int v;
    for( int i = head[u] ; i != -1; i = next1[i])
    {
        v = to[i] ;
        if(v==fa||vi[v]) continue ;
        find_root1(v,u,root,sum) ;
    }
}

int get_root( int u )
{
    find1(u,-1) ;
    int sum = cnt[u] ;
    int root = u ;
    minn = n ;
    find_root1(u,-1,root,sum) ;
    return root ;
}
int ret ,MAX,num[maxn],val[maxn] ;
LL c[maxn];
int gcd(int a,int b)
{
    int c;
    while(b)
    {
        c = a%b ;
        a = b ;
        b = c ;
    }
    return a ;
}
int num1,num2;
vector<int>q;
void find(int d)
{
    int x,n=q.size();
    for(int i =0 ; i < n ;i++)
    {
        x = gcd(q[i],d) ;
        c[x] += num[q[i]] ;
    }
}
void dfs1(int u ,int fa,int root,int d )
{
    vec.push_back(d);
    c[d]++;
   /* if(d==1)c[1] += num1 ;
    else if(d==2) c[2] += num2 ;*/
    find(d) ;
    int j,v ;
    for( int i = head[u] ; i != -1 ; i = next1[i])
    {
         v = to[i] ;
        if(vi[v]||v==fa) continue ;
        dfs1(v,u,1,gcd(d,val[v])) ;
    }
}
int que[maxn],l;
void count( int u )
{
    int j,v ;
    l=0;
    num1=num2=0;
    q.clear();
    for( int i = head[u] ; i != -1 ; i = next1[i])
    {
        v = to[i] ;
        if(vi[v]) continue ;
        vec.clear() ;
        dfs1(v,u,-1,gcd(val[u],val[v]));
        for( j = 0 ; j < vec.size();j++){
            if(num[vec[j]]==0)q.push_back(vec[j]);
            num[vec[j]]++ ;
            num1++;
            if(vec[j]&1){}
            else num2++;
            que[l++]=vec[j];
        }
    }
    for( int i = 0 ; i < l ;i++)
        num[que[i]] = 0;
}
void solve( int u )
{
    int root = get_root(u) ;
    vi[root] = 1 ;
    count(root) ;
    int v ;
    for( int i = head[root] ; i != -1 ; i = next1[i])
    {
        v = to[i] ;
        if(vi[v]) continue ;
        solve(v) ;
    }
}

int main()
{
    int i ,  m ,k , j ;
    int x,y;
    while(scanf("%d",&n) != EOF)
    {
        MAX=0;
        memset(c,0,sizeof(c)) ;
        memset(num,0,sizeof(num));
        for( i = 1 ; i <= n ;i++){
            scanf("%d",&val[i]) ;
            c[val[i]]++;
            MAX=max(MAX,val[i]) ;
        }
        memset(head,-1,sizeof(head)) ;
        memset(vi,0,sizeof(vi));
        top=0;
        for(i = 1 ; i < n ;i++)
        {
            scanf("%d%d",&x,&y) ;
            Unit(x,y) ;
            Unit(y,x) ;
        }
        solve(1) ;
        for( i =1 ; i <= MAX;i++)if(c[i]>0)
        {
           cout<<i<<" "<<c[i]<<endl;
        }
    }
    return 0 ;
}

时间: 2024-12-12 11:32:01

hihoCoder挑战赛4 光棍节的相关文章

光棍节程序员闯关秀(总共10关)

程序员闯关大挑战: https://1111.segmentfault.com/ 仓鼠演示7k7k.4399小游戏: http://cdn.abowman.com/widgets/hamster/hamster.swf 第一关 提示: 从所有信息中找到进入下一关的方法 这一关很简单,即使没有任何web知识也能轻松通过.只要你懂得晃鼠标~~ 查看源代码会发现有这么一行: <p><astyle="color: #172024"href="?k=7a2546077

光棍节的快乐 NYOJ 451

#include<stdio.h>//光棍节的快乐(451) long long f(int x) { long long res=1,i; for(i=1;i<=x;i++){ res=res*i; } return res; } long long g(int x) { if(x==2)return 1; else if(x==3)return 2; else return (x-1)*(g(x-1)+g(x-2)); } int main() { long long m,n,t,r

光棍节的快乐

光棍节的快乐 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描述 光棍们,今天是光棍节.聪明的NS想到了一个活动来丰富这个光棍节. 规则如下: 每个光棍在一个纸条上写一个自己心仪女生的名字,然后把这些纸条装进一个盒子里,这些光 棍依次抽取一张纸条,如果上面的名字就是自己心仪的女生,那么主持人就在现场给该女生打电话,告诉这个光棍对她的爱慕之情,并让光棍当场表白,并得到现场所有人的祝福,没抽到的,嘿嘿就可以幸免了. 假设一共有N个光棍,其中有M个没有抽到自己的纸条,求发生这

光棍节程序员闯关秀writeup

答题链接https://1111.segmentfault.com/ 第一关 首先当然是右键查看源码啊 点击链接进入下一关 第二关 还是老样子,右键查看源码 这个key是要放在URL链接里敲回车的 第三关 根据前两关这个难度,第三关估计在请求头或者响应头里,先开burp 刷新,拦截返回包 拿到flag 第四关 根据前几次规律,都是在改k的参数 对他进行MD5解码 明文是4,这又是第4关,猜测第五关是5的MD5 第五关 扫码,发现什么都没有 难倒是图片隐写术?上工具 得到key 第六关 给我的感觉

光棍节的表白句子说说,光棍节的由来

光棍节的说说 摘要:情侣们可以把每一个节日都过成情人节,单身们可以把每一个节日都过成光棍节. 1.那些暗恋我的人啊,你们怎么那么沉得住气啊! 2.其实我过不过光棍节无所谓,只要我喜欢的人也过光棍节就好了. 3.光棍节在家玩连连看,然后一对一对的消灭你们. 4.对于光棍而言,光棍节就好像大姨妈一样,来一次痛一次. 5.光棍节让我一个人过,情人节让我一个人过,平安夜让我一个人过,圣诞节让我一个人过,有本事考试也让我一个过啊! 6.有没有人和我一样,每次都过光棍节,但也每次错过情人节. 7.有人问我光

程序员的光棍节 你懂吗

每到11.11,大家第一个反应就是天猫的双11,但是可别忘了,最最开始这可代表着光棍节啊! 其实,小编是直到大学才知道有这么个节日的存在,那个时候一定也不放在心上,"妹子是什么,能和我打魔兽玩DOTA不?"大学毕业之后,这个节日慢慢演变成了疯狂购物节,小编就更没啥想法了"因为偶不是剁手党哦!".但是现在,看到身边渐渐地都开始成双入对,突然觉得今天貌似有点寂寞啊! 唉,可怜滴骚年啊! --没有女朋友的,到底是要过光棍节呢,还是要过(guang)双(gun)十(jie)

光棍节脱单,单身狗该你上了

11.11---  一年一度的光棍节到了,又到了装逼的最佳时间. 光棍节是单身狗的硬伤,同时也是已婚男淫最害怕过的节日. 女人这个动物,据说她们非常善良,喜欢养小动物,什么捷豹呀,悍马,路虎,当然还有天猫. 这TM前提是你得有一个女朋友.没女朋友你说个毛啊? 对于屌丝没有女朋友,我深深地表示↓↓↓↓↓ 双十一,弱弱的问一句,你想脱单吗? 来兄弟连学习云计算架构湿吧! 架构湿,湿湿de,单身狗值得拥有. 来兄弟连学习你就可以实现骚动的梦想. 因为,他们都拿到了 高薪.高薪.高薪 对于从兄弟连毕业拿

光棍节,兄弟连UI学科带你装逼带你飞!

自盘古开天辟地万物成形,男人出现不久,一种叫"女人"的生物也顺应而生,万万没想到啊,女人修炼到最后会变成一种称为"丈母娘"的终极体--如何搞定大BOSS丈母娘,经兄弟连各位老师前仆后继奋不顾身的实践,终于获得最深奥义:先搞定女朋友,丈母娘发什么大招都是浮云! 男人,除了要对自己狠一点,谈恋爱这回事,最重要的是比翼双飞,世界上最远的距离不是异地恋,而是妹子在试新内衣你却认真的看代码--女人,是一种神奇的生物,她跑步可能跑不过你,但是逛街你一定不是她的对手:女人也不是不

如何缓解双11光棍节物流爆棚之困。

我的创意idea快递公司与地图软件公司合作推出一款软件,通过地图上显示快递运送过程,当快递员快要到达顾客预先设置的地点时,自动发送短信提醒顾客碰头接货,顾客也可以从地图上时时了解快递员的位置. 地理位置通过扫描二维码收集,就像微信位置分享功能(淘宝地址填写需要这个) 优点:1节约询问具体位置的时间. 2快递员送货多,扫描位置二维码,选择最短的路线. 3大批快递兼职人员的加入.(起点--目的地非常清楚) 对地图公司.淘宝等网站.快递公司有好处有分享给相关公司客服人员. 我,淡泊不名利,寻伯乐,发挥