多校6 GCDispower(容斥)

题意:

给一个长度为\(n\)的排列

给q组询问 每次查询\(L,R\)内的答案

\(\sum_{i=L}^{R}\sum_{j=i+1}^{R}\sum_{k=j+1}^{R}(gcd(a[i],a[j])==a[k]) \cdot a[k]\)

题解:

考虑离线做法,固定右端点\(r\),维护每个左端点\(l\)的答案,

那么对于一个新加进来的\(A_r\), 枚举他的倍数,找出\(A_i\)满足,\(i < r\)的位置,

那么问题相当于所有\(A_i / A_r\)之后,对于任意一组\((A_i, A_j)\)满足\(i < j\) && \(gcd(A[i], A[j]) == 1\),对于左端点\(1\)到\(i\)的答案数就要加\(A_r\),

因此在这些\(A_r\)的倍数这些位置,每个位置\(x\)对左端点在\([1, x]\)位置的贡献为\(x <= i < r\)这些\(Ai / Ar\)的互质个数,这个可以在从右往左扫的过程中,利用在质因子上做容斥求出,然后用树状数组维护一下答案即可。由于给的是一个全排列,每个数字枚举他的倍数均摊下来是\(n\log(n)\)。

总体的时间复杂度是\(O(n\log^{2}n)\)。

个人理解:

前面几步都想得到,如何对这些数做容斥才是关键

以前容斥的题都是求一个数与一段连续的区间数字互质的个数, 都是将这段区间除以这个数的每个质因子的组合,

这里的做法实在是巧妙

两个数不互质,说明存在相同的质因子组合,求一个数的不互质个数实际上是容斥计算它的所有质因子组合的个数

要更新就是更新质因子组合的个数

#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ls rt<<1
#define rs (rt<<1|1)
using namespace std;
int read(){
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - 48, c = getchar();
return x;
}
const int N = 1e5 + 10;
int a[N],pos[N];
int b[N];
int vis[N];
vector<int> v[N];
vector<P> fac[N];
int value[N];
LL s[N];
LL ans[N];
int n, q;
struct query{
int l,r,id;
bool operator<(const query &rhs)const{
return r < rhs.r;
}
}qr[N];
int lowbit(int x){return x &(-x);}
void up(int pos,LL val){
while(pos <= n){
s[pos] += val;
pos += lowbit(pos);
}
}
LL getsum(int pos){
LL ans = 0;
while(pos){
ans += s[pos];
pos -= lowbit(pos);
}
return ans;
}
void init(){
memset(vis,0,sizeof(vis));
for(int i = 2;i < N;i++){
if(!vis[i]){
v[i].push_back(i);
for(int j = 2 * i;j < N;j+=i) {
v[j].push_back(i);
vis[j] = 1;
}
}
}
for(int i = 2;i < N;i++){
int sz = v[i].size();
for(int s = 0;s < (1<<sz);s++){
fac[i].push_back(P(1,1));
for(int j = 0;j < sz;j++) {
if((1<<j) & s){
fac[i][s].first *= v[i][j];
fac[i][s].second *= -1;
}
}
}
}
}
LL cal(int x){
LL ans = 0;
for(int i = 0;i <fac[x].size();i++) ans += value[fac[x][i].first] * fac[x][i].second;
return ans;
}
void up_cal(int x,int val){
for(int i = 0;i < fac[x].size();i++) value[fac[x][i].first] += val;
}
int main(){ init();
int T = read();
while(T--){
n = read(),q = read();
memset(pos,0,sizeof(pos));
for(int i = 1;i<= n;i++){
a[i] = read();
pos[a[i]] = i;
}
for(int i = 0;i < q;i++){
qr[i].l = read(),qr[i].r = read();
qr[i].id = i;
}
memset(ans,0,sizeof(ans));
memset(s,0,sizeof(s));
sort(qr, qr + q);
int now = 0;
for(int i = 1;i <= n;i++){
int cnt = 0,x = a[i];
for(int j = 2 * x;j < N;j+=x) {
if(pos[j] && pos[j] < i ) b[cnt++] = pos[j];
}
sort(b, b + cnt);
for(int j = cnt - 1;j >= 0;j--){
LL tmp = cal(a[b[j]] / x);
up(1,tmp * x);
up(b[j]+1,-tmp * x);
up_cal(a[b[j]] / x,1);
}
for(int j = cnt - 1;j >= 0;j--) up_cal(a[b[j]] / x, -1);
while(now < q && qr[now].r <= i){
ans[qr[now].id] = getsum(qr[now].l);
now++;
}
}
for(int i = 0;i < q;i++) printf("%lld\n",ans[i]);
}
return 0;
}

hdu 6102 GCDispower的更多相关文章

  1. HDU 6102 - GCDispower | 2017 Multi-University Training Contest 6

    个人感觉题解的复杂度很玄,参不透,有没有大佬讲解一下- - /* HDU 6102 - GCDispower [ 数论,树状数组] | 2017 Multi-University Training C ...

  2. 17多校6 HDU - 6102

    题意:给一个排列p,m次查询l,r,\(\sum_{i=l}^r\sum_{j=i+1}^r\sum_{k=j+1}^r[gcd(p_i,p_j)==p_k]p_k\) 题解:离线,枚举右端点,对于每 ...

  3. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  4. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  5. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  6. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  7. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

  8. HDU 1796How many integers can you find(容斥原理)

    How many integers can you find Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d ...

  9. hdu 4481 Time travel(高斯求期望)(转)

    (转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...

随机推荐

  1. ORM初级实战简单的数据库交互

    setting.py中: """ Django settings for untitled3 project. Generated by 'django-admin st ...

  2. 在React Native中集成热更新

    最近,在项目DYTT集成了热更新,简单来说,就是不用重新下载安装包即可达到更新应用的目的,也不算教程吧,这里记录一下. 1.热更新方案 目前网上大概有两个比较广泛的方式,分别是 react-nativ ...

  3. 使用file_get_contents()和curl()抓取网络资源的效率对比

    使用file_get_contents()和curl()抓取网络资源的效率对比 在将小程序用户头像合成海报的时候,用到了抓取用户头像对应的网络资源,那么抓取方式有很多,比如 file_get_cont ...

  4. WPF仿QQ聊天框表情文字混排实现

    原文:WPF仿QQ聊天框表情文字混排实现 二话不说.先上图 图中分别有文件.文本+表情.纯文本的展示,对于同一个list不同的展示形式,很明显,应该用多个DataTemplate,那么也就需要Data ...

  5. JsBridge "Uncaught TypeError: Cannot call method 'callHandler' of undefined", source

    h5和原生结合开发app越来越流行.其实就是webview 的js调用native的方法.也就是需要搭建一个桥.这样的桥早就有人搭建好了,那就是jsbridge. git地址: https://git ...

  6. 起始授权机构(SOA)

    起始授权机构 编辑 本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧! 起始授权机构,SOA(Start Of Authority):该记录表明DNS名称服务器是DNS域中的数据 ...

  7. 程序员需要的各种PDF格式电子书【附网盘免费下载资源地址】

    程序员需要的各种PDF格式电子书[附网盘免费下载资源地址]   各位,请妥善保存,后期还会有更多更新,如果你有不同的书籍资源或者这里没有你要找的书籍,也可以直接留言,后期我们会继续更新~ Java & ...

  8. Spring进阶—如何用Java代码实现邮件发送(一)

    相关文章: <Spring进阶—如何用Java代码实现邮件发送(二)> 在一些项目里面如进销存系统,对一些库存不足发出预警提示消息,招聘网站注册用户验证email地址等都需要用到邮件发送技 ...

  9. 使用Html5shiv.js让ie支持html5

    ie低版本不支持html5标签,可以引入一段脚本,在ie浏览器中创建html5的标签. 1,可以在网上下载html5shiv的压缩包,引入压缩版的html5shiv.min.js即可. 脚本引用要在h ...

  10. 1、shader简介、渲染管线

    vs对于shader的插件:http://blog.shuiguzi.com/shaderlabvs-release-page.html 计算机有一块重要的组成部分,就是“显卡”,大家玩游戏的话,肯定 ...