给定t(t<=1e5)组询问,每次给定l,r(1<=l<=r<=2e5,l+2<=r),
询问在[l,r]之间互不相等的i,j,k(i
和easy的区别仅在于询问数量,easy是5组询问,允许离线
看了红名爷的代码就会了
首先直接统计不好统计,然后考虑用总的减去不满足条件的
对不满足条件的小范围打了个表,发现只有两种情况,
1. lcm(i,j,k)=k,即i|k且j|k,所以枚举k的约数统计
2. lcm(i,j,k)=2k,此时有i和j均是2k的因子且i和j在2的因子个数之和比k多一个的结论,可惜这个结论没啥用,进一步观察打表结果发现,只可能是(3,4,6)和(6,10,15)这两种情况及其倍数,这就可以做了
easy的时候搞了一个指针每次暴力扫到合法的位置,O(qnlogn)
hard就是把询问离线,指针扫的时候插到BIT上,相当于(i,j,k),枚举k使之不超过当前r的限制,把对于i来说当前满足j的个数插入在i的位置,查询时只查满足条件的段,O(qlogq+n(logn)^2)
BIT常见套路,然而看着1e5组询问,值域2e5,
赛中过了easy之后全在想怎么莫队,然后发现会转移右端点不会转移左端点,过于睿智
bonus:想想1log咋做
- #include
- using namespace std;
- const int N=2e5+10;
- typedef long long ll;
- int t,l,r,L,R;
- vector<int>fac[N];
- void init(){
- for(int i=1;i
- for(int j=2*i;j
- fac[j].push_back(i);
- }
- }
- }
- ll C2(int x){
- return 1ll*x*(x-1)/2;
- }
- ll C3(int x){
- return 1ll*x*(x-1)*(x-2)/6;
- }
- int main(){
- init();
- scanf("%d",&t);
- while(t--){
- scanf("%d%d",&l,&r);
- ll ans=C3(r-l+1);
- for(int k=l+2;k<=r;++k){
- int id=0;
- while(id
size() && fac[k][id] - if(id>=fac[k].size())continue;
- int sz=fac[k].size()-id;
- ans-=C2(sz);
- }
- L=(l+2)/3,R=r/6;//(3,4,6)
- ans-=max(0,R-L+1);
- L=(l+5)/6,R=r/15;//(6,10,15)
- ans-=max(0,R-L+1);
- printf("%lld\n",ans);
- }
- return 0;
- }
代码2(hard)
- #include
- using namespace std;
- const int N=2e5+10;
- typedef long long ll;
- int t,L,R,tr[N];
- ll ans[N];
- vector<int>fac[N];
- struct node{
- int l,r,id;
- }e[N];
- bool operator<(node a,node b){
- return a.r
- }
- void add(int x,int v){
- for(int i=x;i
- tr[i]+=v;
- }
- }
- int sum(int x){
- int ans=0;
- for(int i=x;i;i-=i&-i){
- ans+=tr[i];
- }
- return ans;
- }
- void init(){
- for(int i=1;i
- for(int j=2*i;j
- fac[j].push_back(i);
- }
- }
- }
- ll C2(int x){
- return 1ll*x*(x-1)/2;
- }
- ll C3(int x){
- return 1ll*x*(x-1)*(x-2)/6;
- }
- int main(){
- init();
- scanf("%d",&t);
- for(int i=1;i<=t;++i){
- scanf("%d%d",&e[i].l,&e[i].r);
- e[i].id=i;
- }
- sort(e+1,e+t+1);
- int k=1;
- for(int i=1;i<=t;++i){
- int id=e[i].id,l=e[i].l,r=e[i].r;
- ans[id]=C3(r-l+1);
- for(;k<=r;++k){
- int sz=fac[k].size();
- for(int i=0;i
- add(fac[k][i],sz-1-i);
- }
- }
- ans[id]-=sum(r)-sum(l-1);
- L=(l+2)/3,R=r/6;//(3,4,6)
- ans[id]-=max(0,R-L+1);
- L=(l+5)/6,R=r/15;//(6,10,15)
- ans[id]-=max(0,R-L+1);
- }
- for(int i=1;i<=t;++i){
- printf("%lld\n",ans[i]);
- }
- return 0;
- }
-
相关阅读:
leetCode 198.打家劫舍 动态规划
hive创建分区表
认识垃圾回收
同时申请发明专利和实用新型专利的好处
5年没发paper,学术论文写到头秃...
一文2500字手把手教你使用jmeter进行分布式压力测试【保姆级教程】
Could not find androidx.camera:camera-view
为Qt应用程序的用户添加帮助文档
SA8155 QNX 命令
STL容器——vector
-
原文地址:https://blog.csdn.net/Code92007/article/details/126360154