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

  由于每个数字最多是30位,枚举数字每一位考虑,

  建一棵记录前缀(位的前缀,比如10拆成1010,那么就把1010从前往后插入这个字典树中)的字典树,

  nxt记录其后继,gcnt记录这个节点添加的个数,ng代表不符合要减去的个数(后文会提到)

  tol[i][j]代表第i位的j(j=0,1)当前数量

  枚举Ak的每一位,对于Ak的第t位(记作Ak[t])

  1. 如果Ak[t]==1,那么对答案产生贡献的Ai[t]和Aj[t]必然为0,而且Ai[0]~Ai[t-1]必然和Ak[0]~Ak[t-1]对应相等。

   记Ak[t]对应地节点为chil,与其同父亲的另一个节点为xchil

   1) Ak[t]加入后,第一部分要的贡献为 (tree[xchil].gcnt-1)*tree[xchil].gcnt/2 ,这是显然的,就是Ai[0]~Ai[t-1]和Ak[0]~Ak[t-1]和Aj[0]~Aj[t-1]全都相等情况

   2) 第二部分是 tree[xchil].gcnt*(tol[i][1-s[i]]-tree[xchil].gcnt)-tree[xchil].ng ,减号前面的是Ai[0]~Ai[t-1]和Ak[0]~Ak[t-1]相等,且Ak[0]~Ak[t-1]和Aj[0]~Aj[t-1]有所不同的积(这样算出来有不合法的),因为有不合法所以要减去不合法的部分也就是tree[xchi].ng

   而tree[xchi].ng的维护的话,每次加入一个点,那么这个点必然会在当前节点产生 tol[i][s[i]]-tree[chil].gcnt 点不合法的贡献,(Ai[0]~Ai[t-1]和Ak[0]~Ak[t-1]不相等,Ak[0]~Ak[t-1]和Aj[0]~Aj[t-1]相等这种不合法的情况)

  2. 如果Ak[i]==0的话,那么答案也类似可以得到

  

  (思路来自队友DorMOUSENone(队友真是太强辣))

  

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio> using namespace std; typedef long long ll; const int M=5e5+55;
const int N=33;
const int infn=30; struct Node
{
int nxt[2],gcnt;
ll ng;
} tree[M*N]; int n,tnum;
ll ans;
int s[N],tol[N][2]; void insert()
{
int rt=0,i,j,chil,xchil;
for(i=infn-1;i>=0;i--)
{
if(tree[rt].nxt[s[i]]==0)
tree[rt].nxt[s[i]]=++tnum;
chil=tree[rt].nxt[s[i]]; //children for s[i]
xchil=tree[rt].nxt[1-s[i]]; //another children
if(xchil)
ans+=1ll*(tree[xchil].gcnt-1)*tree[xchil].gcnt/2+1ll*tree[xchil].gcnt*(tol[i][1-s[i]]-tree[xchil].gcnt)-tree[xchil].ng;
tree[chil].ng+=tol[i][s[i]]-tree[chil].gcnt;
tree[chil].gcnt++;
tol[i][s[i]]++;
rt=chil;
}
} void init()
{
memset(tree,0,(n+4)*N*sizeof(Node));
memset(tol,0,sizeof(tol));
tnum=0;
ans=0;
} void solve()
{
int i,j,now;
for(i=1;i<=n;i++)
{
scanf("%d",&now);
for(j=0;j<infn;j++)
{
s[j]=now&1;
now>>=1;
}
insert();
}
} int main()
{
int T,now;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
solve();
printf("%lld\n",ans);
}
return 0;
} /* 200
4
1 3 0 0 */

  

327MS代码

#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio> using namespace std; namespace fastIO {
#define BUF_SIZE 100000
//fread -> read
bool IOerror = 0;
inline char nc() {
static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
if(p1 == pend) {
p1 = buf;
pend = buf + fread(buf, 1, BUF_SIZE, stdin);
if(pend == p1) {
IOerror = 1;
return -1;
}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
char ch;
while(blank(ch = nc()));
if(IOerror)
return;
for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
}
#undef BUF_SIZE
};
using namespace fastIO; typedef long long ll; const int M=5e5+55;
const int N=33;
const int infn=30; struct Node
{
int nxt[2],gcnt;
int ng;
} tree[M*N]; int n,tnum;
ll ans;
int s[N],tol[N][2]; void insert()
{
int rt=0,i,j,chil,xchil;
for(i=infn-1;i>=0;i--)
{
if(tree[rt].nxt[s[i]]==0)
tree[rt].nxt[s[i]]=++tnum;
chil=tree[rt].nxt[s[i]];
xchil=tree[rt].nxt[1-s[i]];
if(xchil)
ans+=1ll*(tree[xchil].gcnt-1)*tree[xchil].gcnt/2+1ll*tree[xchil].gcnt*(tol[i][1-s[i]]-tree[xchil].gcnt)-tree[xchil].ng;
tree[chil].ng+=tol[i][s[i]]-tree[chil].gcnt;
tree[chil].gcnt++;
tol[i][s[i]]++;
rt=chil;
}
} void init()
{
memset(tree,0,(n+4)*N*sizeof(Node));
memset(tol,0,sizeof(tol));
tnum=0;
ans=0;
} void solve()
{
int i,j,now;
for(i=1;i<=n;i++)
{
read(now);
for(j=0;j<infn;j++)
{
s[j]=now&1;
now>>=1;
}
insert();
}
} int main()
{
int T,now;
read(T);
while(T--)
{
read(n);
init();
solve();
printf("%lld\n",ans);
}
return 0;
}

  

hdu 6059 Kanade's trio的更多相关文章

  1. HDU 6059 - Kanade's trio | 2017 Multi-University Training Contest 3

    思路来自题解(看着题解和标程瞎吉尔比划了半天) /* HDU 6059 - Kanade's trio [ 字典树 ]  |  2017 Multi-University Training Conte ...

  2. hdu 6059 Kanade's trio(字典树)

    Kanade's trio Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)T ...

  3. hdu6059 Kanade's trio 字典树+容斥

    转自:http://blog.csdn.net/dormousenone/article/details/76570172 /** 题目:hdu6059 Kanade's trio 链接:http:/ ...

  4. HDU 6057 - Kanade's convolution | 2017 Multi-University Training Contest 3

    /* HDU 6057 - Kanade's convolution [ FWT ] | 2017 Multi-University Training Contest 3 题意: 给定两个序列 A[0 ...

  5. HDU 6058 - Kanade's sum | 2017 Multi-University Training Contest 3

    /* HDU 6058 - Kanade's sum [ 思维,链表 ] | 2017 Multi-University Training Contest 3 题意: 给出排列 a[N],求所有区间的 ...

  6. HDU 6059 17多校3 Kanade's trio(字典树)

    Problem Description Give you an array A[1..n],you need to calculate how many tuples (i,j,k) satisfy ...

  7. hdu 6058 Kanade's sum(模拟链表)

    Kanade's sum Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  8. HDU 6057 Kanade's convolution(FWT)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6057 [题目大意] 有 C[k]=∑_(i&j=k)A[i^j]*B[i|j] 求 Ans ...

  9. HDU 6058 Kanade's sum 二分,链表

    Kanade's sum Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th larg ...

随机推荐

  1. Excel 下来公式 内容却一样

    首先我们打开我们电脑里面的excel2007的软件   我们随便输入一点输入,进行公式计算   我们在上边输入=A1+B1,就能算出这个的结果   我们把上边的公式算好了,点击下拉试试   我们发现虽 ...

  2. 利用PLSQL Developer对oracle中的数据进行备份恢复

    --以备份scott用户为例,目标(备份里面所有的对象)--切换到scottconn scott/tiger;--进入  工具-->导出用户对象  如图所示 创建表空间及用户名,并赋予权限 -- ...

  3. 栈与队列基本操作 Java实现

    一.顺序栈 //数组实现顺序栈 public class OrderStack { private String[] elem; private int top; OrderStack(int k) ...

  4. C#实现鼠标滚筒缩放界面的效果

    elementCanvas继承UserControl 声明属性: #region 缩放属性添加 float ratio = 1.0f; public float Ratio { set { ratio ...

  5. C#取绝对值函数

    System.Math.Abs(float value); System.Math.Abs(decimal value); System.Math.Abs(int value); System.Mat ...

  6. 【html】 iframe 和 frameset 的区别

    一.两者的相同点和不同点 相同点: iframe 和frameset都是html布局的框架布局 不同点: iframe是一个内联框架,是在页面里生成内部框架 frameset定义一个框架集,包含多个子 ...

  7. 移动端真机debug调试神器 vConsole学习(一)之基础

    参考 使用方法 移动端真机debug调试神器 vConsole的引入说明(原生态与WebPack) 移动端使用vconsole调试console vConsole ——开源的前端 console 调试 ...

  8. JVM类加载机制和内存模型

    一.JVM类加载机制 首先需要了解一下类加载器(ClassLoader): ClassLoader是Java的一个核心组件,它主要作用是从系统外部获得Class二进制数据流,然后将数据流装载到系统,交 ...

  9. Tomcat设置默认启动项目

    Tomcat设置默认启动项目 Tomcat设置默认启动项目,顾名思义,就是让可以在浏览器的地址栏中输入ip:8080,就能访问到我们的项目.具体操作如下:     1.打开tomcat的安装根目录,找 ...

  10. 如何设置树莓派 -Zero 自启动连接WIFI

    1. 首先我们需要一台可以读取树莓派跟文件系统的Linux虚拟机(比如Ubuntu) 将树莓派SD卡系统插入电脑,识别并打开rootfs文件夹,切换到`rootfs/etc/wpa_supplican ...