[hdu7078]Pty with card
显然问题被分为两部分,先考虑如何求$F(n)$——
令第一次所选的人编号为1,其之后所有人按顺时针依次编号为$2,3,...,n$,那么用一个序列来描述状态,其中第$i$个元素为当前存在的人中编号第$i$小的人手牌数(显然序列长度即为剩余人数)
初始序列显然为$\{1,1,...,1\}$(共$n$个1),并对$n$的奇偶性分类讨论:
1.若$n$为奇数,则$n$轮后序列为$\{3,2,2,...,2\}$(其中共$\frac{n-3}{2}$个2)
2.若$n$为偶数,则$n$轮后序列为$\{4,2,2,...,2\}$(其中共$\frac{n}{2}-2$个2)
(关于这个结果,手动模拟若干次即可得到规律)
注意到此时所有元素都$\ge 2$,那么若序列长度为$2m+1$(其中$m\in Z^{+}$),循环节即恰为$4m+2$
关于这个性质,考虑两轮中每一个人都会在奇数轮操作一次、偶数轮操作一次,那么总共即恰好失去3张卡片并得到3张卡片,因此卡牌数量不变,且由于初始有两张卡片,不会有人"出局"
下面,考虑序列长度为$2m$,再对两类分别讨论:
1.若$n$为奇数(注意不是$m$),则$2m$轮后序列为$\{2,3,1,3,1,3...,1,3\}$(其中共$m-1$对$1,3$),再$2m$轮后序列为$\{5,4,4,...,4\}$(其中共$m-1$个4)
不难发现如果序列长度仍是偶数,其又会变为$\{9,8,8,...,8\},\{17,16,16,...,16\},...$(可以归纳证明),直至序列长度为奇数(答案为序列长度的两倍)
2.若$n$为偶数,类似的$4m$轮后序列为$\{6,4,4,...,4\}$(其中共$m-1$个4),如果序列长度仍是偶数,其又会变为$\{10,8,8,...,8\},\{18,16,16,...,16\},...$,直至序列长度为奇数
(另外,若最终序列长度为1则$F(n)=0$)
综上,有
$$
F(n)=\begin{cases}0&\left(n\le 2\right)\or \left(lowbit(m)=1\right)\\\frac{2m}{lowbit(m)}&\left(n\ge 3\right)\and \left(lowbit(m)\ne 1\right)\end{cases}
$$
(其中$m=\lfloor\frac{n-1}{2}\rfloor$,$lowbit(m)$指$m$二进制下最低位上的1对应的值)
接下来,考虑如何求$\forall 1\le x\le n,\sum_{i=1}^{n}F(v_{i}+d(i,x))$——
将其点分治,问题即是要维护一个集合$S$,支持:1.加入一个元素$x$;2.(给定$x$)查询$\sum_{y\in S}F(x+y)$
这个并不容易维护,但注意到查询中$x$即为某点到当前点分中心的距离,是连续变化的,因此这个问题还可以看作支持:1.加入一个元素$x$;2.令所有元素+1;3.查询$\sum_{x\in S}F(x)$
维护一棵trie树,并且从低到高存储数字,依次考虑这些操作:
1.加入一个元素$x$,与普通的trie树相同
2.令所有元素+1,即不断交换左右儿子,并递归(新的)左儿子即可
3.查询$\sum_{x\in S}F(x)$,不断递归左儿子,维护子树中所有元素的和即可(注意去掉$lowbit(m)=1$的情况)
由此,单次操作时间复杂度为$o(\log n)$,总复杂度即$o(n\log^{2}n)$,可以通过
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define ll long long
5 struct Edge{
6 int nex,to;
7 }edge[N<<1];
8 vector<int>v[N];
9 int E,rt,t,n,x,y,mx,a[N],head[N],vis[N],sz[N],f[N<<2];
10 ll ans[N];
11 int lowbit(int k){
12 return (k&(-k));
13 }
14 namespace Trie{
15 int V,tag,st[N],L[N*6],sz[N*6],ch[N*6][2];
16 ll sum[N*6];
17 int New(){
18 int k=++V;
19 L[k]=sz[k]=sum[k]=ch[k][0]=ch[k][1]=0;
20 return k;
21 }
22 ll get(int k){
23 return sum[k]+(ll)tag*sz[k];
24 }
25 void init(){
26 V=tag=0;
27 New();
28 }
29 void add_val(int x){
30 st[0]=st[1]=1;
31 for(int i=0,k=1;i<18;i++){
32 int p=((x>>i)&1);
33 if (!ch[k][p])ch[k][p]=New();
34 k=st[++st[0]]=ch[k][p];
35 }
36 for(int i=1;i<=st[0];i++)sz[st[i]]++,sum[st[i]]+=x;
37 L[st[st[0]]]=st[st[0]];
38 for(int i=st[0]-1;i;i--)L[st[i]]=L[ch[st[i]][0]];
39 }
40 void Add(){
41 tag++;
42 st[0]=st[1]=1;
43 for(int i=0,k=1;(i<18)&&(k);i++){
44 swap(ch[k][0],ch[k][1]);
45 k=st[++st[0]]=ch[k][0];
46 }
47 L[st[st[0]]]=st[st[0]];
48 for(int i=st[0]-1;i;i--)L[st[i]]=L[ch[st[i]][0]];
49 }
50 ll query(){
51 ll ans=0;
52 for(int i=1,k=ch[1][0];(i<18)&&(k);i++){
53 ans+=(get(ch[k][1])-get(L[ch[k][1]])>>i-1);
54 k=ch[k][0];
55 }
56 tag--;
57 for(int i=1,k=ch[1][1];(i<18)&&(k);i++){
58 ans+=(get(ch[k][1])-get(L[ch[k][1]])>>i-1);
59 k=ch[k][0];
60 }
61 tag++;
62 return ans;
63 }
64 }
65 void add_edge(int x,int y){
66 edge[E].nex=head[x];
67 edge[E].to=y;
68 head[x]=E++;
69 }
70 void get_sz(int k,int fa){
71 sz[k]=1;
72 for(int i=head[k];i!=-1;i=edge[i].nex)
73 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
74 get_sz(edge[i].to,k);
75 sz[k]+=sz[edge[i].to];
76 }
77 }
78 void get_rt(int k,int fa,int s){
79 int mx=s-sz[k];
80 for(int i=head[k];i!=-1;i=edge[i].nex)
81 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
82 get_rt(edge[i].to,k,s);
83 mx=max(mx,sz[edge[i].to]);
84 }
85 if (mx<=(s>>1))rt=k;
86 }
87 void get_val(int k,int fa,int s){
88 if (mx<s)v[++mx].clear();
89 v[s].push_back(k);
90 Trie::add_val(a[k]+s);
91 for(int i=head[k];i!=-1;i=edge[i].nex)
92 if ((!vis[edge[i].to])&&(edge[i].to!=fa))get_val(edge[i].to,k,s+1);
93 }
94 void calc(int k,int p){
95 Trie::init();
96 mx=0,v[0].clear();
97 get_val(k,0,p);
98 p=1-(p<<1);
99 for(int i=0;i<=mx;i++){
100 ll s=Trie::query();
101 for(int j=0;j<v[i].size();j++)ans[v[i][j]]+=p*s;
102 Trie::Add();
103 }
104 }
105 void dfs(int k){
106 get_sz(k,0);
107 get_rt(k,0,sz[k]);
108 calc(rt,0);
109 vis[rt]=1;
110 for(int i=head[rt];i!=-1;i=edge[i].nex)
111 if (!vis[edge[i].to])calc(edge[i].to,1);
112 for(int i=head[rt];i!=-1;i=edge[i].nex)
113 if (!vis[edge[i].to])dfs(edge[i].to);
114 }
115 int main(){
116 for(int i=2;i<(N<<2);i++)
117 if (lowbit(i>>1)==1)f[i]=0;
118 else f[i]=((i>>1)/lowbit(i>>1)<<1);
119 scanf("%d",&t);
120 while (t--){
121 scanf("%d",&n);
122 E=0;
123 memset(head,-1,sizeof(head));
124 memset(vis,0,sizeof(vis));
125 memset(ans,0,sizeof(ans));
126 for(int i=1;i<=n;i++){
127 scanf("%d",&a[i]);
128 a[i]--;
129 }
130 for(int i=1;i<n;i++){
131 scanf("%d%d",&x,&y);
132 add_edge(x,y);
133 add_edge(y,x);
134 }
135 dfs(1);
136 for(int i=1;i<n;i++)printf("%lld ",ans[i]);
137 printf("%lld\n",ans[n]);
138 }
139 return 0;
140 }
[hdu7078]Pty with card的更多相关文章
- Lesson 3 Please send me a card
Text Postcards always spoil my holidays. Last summer, I went to Italy. I visited museums and sat in ...
- iOS - Card Identification 银行卡号识别
1.CardIO 识别 框架 GitHub 下载地址 配置 1.把框架整个拉进自己的工程,然后在 TARGETS => Build Phases => Link Binary With L ...
- bzoj3756: Pty的字符串
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- HDOJ 4336 Card Collector
容斥原理+状压 Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- Opensuse enable sound and mic card
Install application pavucontrol Run pavucontrol You will see the configuration about sound card and ...
- 进监狱全攻略之 Mifare1 Card 破解
补充新闻:程序员黑餐馆系统 给自己饭卡里充钱 ,技术是双刃剑,小心,小心! 前言 从M1卡的验证漏洞被发现到现今,破解设备层出不穷,所以快速傻瓜式一键破解不是本文的重点,年轻司机将从本文中获得如下技能 ...
- Card(bestcoder #26 B)
Card Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- [OpenJudge 3061]Flip The Card
[OpenJudge 3061]Flip The Card 试题描述 There are N× Ncards, which form an N× Nmatrix. The cards can be p ...
- [杂谈]交通工具orca card
How and Where to Use the ORCA Card The Microsoft ORCA card provides unlimited rides on all buses, tr ...
随机推荐
- Java AES 加密小试牛刀
目录 问题出处 解决方法 方法一 方法二 方法三 补充 总结 在java开发过程中,很多时候我们都需要加密数据,例如声音.敏感信息等.我们通常使用的是 MD5加密.SHA加密.DES 加密.AES 加 ...
- Java(13)详解构造方法
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201600.html 博客主页:https://www.cnblogs.com/testero ...
- 苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功
苹果应用内购 ios 开发者根据用户提供的邮件中的订单号查看该订单是否支付成功 这是苹果wwdc2021 推出的新功能 参考官网链接 App Store Server API | Apple Deve ...
- NX Open显示符号(UF_DISP_display_temporary_point)
UF_DISP_display_temporary_point 使用方法: 1 Dim x As Double = 0, y As Double = 0, z As Double = 0 2 3 Di ...
- [技术博客] 通过ItemTouchHelper实现侧滑删除功能
通过ItemTouchHelper实现侧滑删除功能 一.效果 二.具体实现 demo中演示的这种左滑删除的效果在手机APP中比较常用,安卓也为我们提供了专门的辅助类ItemTouchHelper来帮助 ...
- 进阶区forgotg攻防世界
攻防世界进阶区--forgot 前言,这题中看不中用啊宝友!!! 1.查看保护 第一反应就是蛮简单的,32位. 2.获取信息(先运行程序看看) 装的可以,蛮多的东西. 但是就是中看不中用 3.ida ...
- Noip模拟37 2021.8.12
T1 数列 真是考场上不是数学的乱推柿子,想定理,是数学的没想出来.. 比较悲伤... 列柿子不用动脑子,就是没有想出来$EXgcd$解不定方程,淦.. 解处一组解后利用比较显然的性质: $x+\fr ...
- 2021.1.8 NKOJ 周赛总结
意料之中..... A:nkoj 3900 AC小程序 http://oi.nks.edu.cn/zh/Problem/Details/3900 A题比较简单,单独分析一下A和C,其实就是一个斐波那契 ...
- 零基础入门c语言函数之递归函数
今天来总结一下关于递归函数的使用方面的问题. 递归函数就是在函数使用的时候自己调用自己,层层调用,来实现你想要的功能. 有两个最常用的例子,我们来写一下. (1)计算阶乘 #include int f ...
- 对dy和Δy的浅薄理解
一.导数定义 当函数y=f(x)的自变量x在一点x0上产生一个增量Δx时,函数输出值的增量Δy与自变量增量Δx的比值在Δx趋于0时的极限a如果存在,a即为在x0处的导数,记作f'(x0)或df(x0) ...