关闭

[bzoj4815][CQOI2017]小Q的表格

310人阅读 评论(0) 收藏 举报
分类:

题目描述

小Q是个程序员。
作为一个年轻的程序员,小Q总是被老C欺负,老C经常把一些麻烦的任务交给小Q来处理。每当小Q不知道如何解决
时,就只好向你求助。为了完成任务,小Q需要列一个表格,表格有无穷多行,无穷多列,行和列都从1开始标号。
为了完成任务,表格里面每个格子都填了一个整数,为了方便描述,小Q把第a行第b列的整数记为f(a,b),为了完成
任务,这个表格要满足一些条件:(1)对任意的正整数a,b,都要满足f(a,b)=f(b,a);(2)对任意的正整数a,b,都要
满足b×f(a,a+b)=(a+b)*f(a,b)。为了完成任务,一开始表格里面的数很有规律,第a行第b列的数恰好等于a*b,
显然一开始是满足上述两个条件的。为了完成任务,小Q需要不断的修改表格里面的数,每当修改了一个格子的数
之后,为了让表格继续满足上述两个条件,小Q还需要把这次修改能够波及到的全部格子里都改为恰当的数。由于
某种神奇的力量驱使,已经确保了每一轮修改之后所有格子里的数仍然都是整数。为了完成任务,小Q还需要随时
获取前k行前k列这个有限区域内所有数的和是多少,答案可能比较大,只需要算出答案mod1,000,000,007之后的结
果。

性质

1、f(a,b)=f(b,a)
2、f(a,b)*(b-a)=f(a,b-a)*b
即f(a,b)/b=f(a,b-a)/(b-a)
考虑影响情况。
(a,b)<=>(b,a)
(a,b)<=>(a,b-a)
这是个辗转相除。
因此我们容易发现gcd相同的值会互相影响。
注意到对于(a,x),(a,b)和(y,b)互相的关系(gcd(a,x)=gcd(a,b)=gcd(y,b))。
f(a,x)/x=f(a,b)/b
f(a,b)/a=f(y,b)/y
容易发现对于gcd(x,y)=gcd(a,b)一定有f(x,y)/xy=f(a,b)/ab。
于是只需要保存a[i]=f(i,i)。
那么f(id,jd)=a[d]*ij其中(i,j)=1。
因此答案很容易计算,修改也很容易修改。
nd=1a[d]n/di=1n/dj=1[(i,j)=1]ij
后面部分可以设为g[n/d],考虑如何预处理它。

莫比乌斯意义

ni=1nj=1[(i,j)=1]ij
ni=1nj=1ijd|i,d|jμ(d)
nd=1μ(d)d2S(n/d)2
其中S(n)=ni=1i
这个玩意可以n log n预处理,但还是不够快啊?
考虑作差,g[n]-g[n-1]是啥呢?
我们找到所有n/d!=(n-1)/d的d,那么d一定整除n。
d|nμ(d)d2[S(n/d)2S(n/d1)2]
d|nμ(d)d2[S(n/d)+S(n/d1)][S(n/d)S(n/d1)]
d|nμ(d)d2[2S(n/d)n/d]n/d
d|nμ(d)d2(n/d)3
n2d|nμ(d)n/d
n2ϕ(n)
这个为啥变成phi了?你考虑容斥意义理解即可。
于是线性筛phi,然后前缀和。

欧拉意义

也可以直接欧拉意义下理解。
考虑i>j,(i,j)=1。
我们知道当i>1时,所有和i互质的数两两配对,每两个的和都是i。
所以贡献和为iiϕ(i)/2
注意到在j的时候也要算i,但是我们只考虑i>j,所以贡献乘2,就是
iiϕ(i)
i=1也恰好满足。

求答案

现在处理了g,可以每次分块计算。
我们需要支持修改和区间求和。
注意到修改m次,而求和有m sqrt n 次。
因此我们用分块维护,修改O(sqrt n),而询问O(1)。
即可平衡。

#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=4000000+10,B=2000,mo=1000000007;
int sum[B+10],num[maxn],a[maxn],belong[maxn];
int pri[maxn],phi[maxn],g[maxn];
bool bz[maxn];
int i,j,k,d,y,l,t,n,m,p,tot,top,ans;
ll x;
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
int getsum(int x){
    if (!x) return 0;
    int i,t=0,y=belong[x];
    t=sum[y-1];
    (t+=num[x])%=mo;
    return t;
}
int qsm(int x,int y){
    if (!y) return 1;
    int t=qsm(x,y/2);
    t=(ll)t*t%mo;
    if (y%2) t=(ll)t*x%mo;
    return t;
}
int main(){
    scanf("%d%d",&m,&n);
    fo(i,1,n){
        belong[i]=(i-1)/B+1;
        a[i]=(ll)i*i%mo;
        if (belong[i]==belong[i-1]){
            num[i]=(num[i-1]+a[i])%mo;
            (sum[belong[i]]+=a[i])%=mo;
        }
        else{
            num[i]=a[i];
            sum[belong[i]]=(sum[belong[i]-1]+a[i])%mo;
        }
    }
    phi[1]=1;
    fo(i,2,n){
        if (!bz[i]){
            pri[++top]=i;
            phi[i]=i-1;
        }
        fo(j,1,top){
            if ((ll)i*pri[j]>n) break;
            bz[i*pri[j]]=1;
            if (i%pri[j]==0){
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            phi[i*pri[j]]=phi[i]*(pri[j]-1);
        }
    }
    fo(i,1,n) g[i]=(g[i-1]+(ll)i*i%mo*phi[i]%mo)%mo;
    while (m--){
        scanf("%d%d%lld%d",&j,&k,&x,&p);
        t=x%mo;
        d=gcd(j,k);
        t=(ll)t*qsm(j/d,mo-2)%mo*qsm(k/d,mo-2)%mo;
        a[d]=t;
        y=belong[d];
        l=0;
        fo(i,(y-1)*B+1,min(y*B,n)){
            num[i]=(l+a[i])%mo;
            l=num[i];
        }
        (l+=sum[y-1])%=mo;
        l=(l-sum[y])%mo;
        fo(i,y,belong[n]) (sum[i]+=l)%=mo;
        ans=0;
        i=1;
        while (i<=p){
            j=p/(p/i);
            t=(getsum(j)-getsum(i-1))%mo;
            (ans+=(ll)t*g[p/i]%mo)%=mo;
            i=j+1;
        }
        (ans+=mo)%=mo;
        printf("%d\n",ans);
    }
}
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Solr -- 查询语法/参数

1. 常用查询参数 参数 描述 defType 指定用于处理查询语句(参数q的内容)的查询解析器,eg:defType=lucene sort 指定响应的排序方式:升序asc或降...
  • zhufenglonglove
  • zhufenglonglove
  • 2016-05-27 18:11
  • 16845

DSP上浮点数据定点化处理 Q格式(Q15)

许多DSP都是定点DSP,处理定点数据会相当快,但是处理浮点数据就会非常慢。可以利用Q格式进行浮点数据到定点的转化,节约CPU时间。实际应用中,浮点运算大都时候都是既有整数部分,也有小数部分的。所以要...
  • HengZo
  • HengZo
  • 2015-12-10 22:07
  • 3163

priority_queue 的简单使用方法

优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队...
  • u013476556
  • u013476556
  • 2014-08-04 17:26
  • 2120

【CQOI2017】bzoj4815 小Q的表格

辗转相减+莫比乌斯反演+分块
  • sdfzyhx
  • sdfzyhx
  • 2017-04-13 10:22
  • 783

[分块 莫比乌斯反演] BZOJ 4815 [Cqoi2017]小Q的表格

那个神奇的关系式 其实是辗转相减的形式 稍微发现下就能知道 这其实是个一维的东西 fa,b=abgcd2(a,b)∗fgcd(a,b),gcd(a,b)f_{a,b}={ab\over gcd^2...
  • u014609452
  • u014609452
  • 2017-04-21 08:20
  • 327

4815: [Cqoi2017]小Q的表格

4815: [Cqoi2017]小Q的表格Time Limit: 20 Sec Memory Limit: 512 MB Submit: 496 Solved: 209 [Submit][St...
  • CRZbulabula
  • CRZbulabula
  • 2017-05-03 11:39
  • 409

CQOI 2017 小Q的表格 - 不一样的暴力

题目太长了略去不表。   听说这个题正解是O(n+mn√)O(n+m\sqrt n)的,然而我太菜只会暴力。下面来讲讲我的搞笑做法。
  • GEOTCBRL
  • GEOTCBRL
  • 2017-06-14 13:53
  • 420

cqoi2017,bzoj4813小Q的棋盘(树形dp或瞎搞)

1.前言 我现在很气。 考试的时候想着写树形dp,结果因为脑残以为要多叉转二叉而写挂了。挂了之后我瞎搞一通,结果居然50分,我特别奇怪地加了个步数可以把整棵树走一边就输出n的特判,就蜜汁AC了,这!什...
  • litble
  • litble
  • 2017-04-12 14:14
  • 671

BZOJ 4813 [Cqoi2017]小Q的棋盘

树形dp
  • Rlt1296
  • Rlt1296
  • 2017-04-12 11:50
  • 515

NKOJ 4038(CQOI 2017) 小Q的棋盘(贪心)

考虑到是一颗树,所以先找出从0号点出发的最长链,假设长度为L。 如果L>=N,那么答案就是N+1 如果L<N,此时肯定发生了某些点走两次的情况,那么最优解就是在一些链上走2次,最后在最长链上走...
  • Mogician_Evian
  • Mogician_Evian
  • 2017-07-20 23:26
  • 218
    个人资料
    • 访问:327189次
    • 积分:11634
    • 等级:
    • 排名:第1512名
    • 原创:814篇
    • 转载:4篇
    • 译文:0篇
    • 评论:201条
    最新评论
    文章分类