zoukankan      html  css  js  c++  java
  • lagrange-CSP.ac

    题目

    有两个序列长(n)(A_i)(B_i),需要进行两种操作,共进行(q)

    (查询区间 sum_{lleq i<jleq r}{(A_iB_j - A_jB_i)}的值,结果对 998244353 取模)

    (把 (A_i , B_i) 修改为 (x,y))

    对于(20 \%)的数据,(n,q≤200)
    对于(40 \%)的数据,(n,q≤2000)
    对于另外(30 \%)的数据,仅有操作查询操作
    对于(100 \%)的数据,(n,q≤500000,1leq A_i,x,B_i,x,yleq 10^9)

    考场思路

    (8:30)开考,写了5分钟文化课作业才意识到发卷了

    开卷看(T1),本来想手推出式子啥的,结果能力有限(()毕竟不是数竞

    然后打了个表,秒切。

    (15)分钟开(T2)
    感觉可做,但完全想不到优化的策略,打了个暴力,写了个对拍,溜了溜了

    (T3),看到这个题,直接联想线段树维护,但困难出现在区间合并问题上,想了半个小时无果,放弃T3,写了个(20)分暴力溜了,

    (T4)
    (:******????),直接联想到不可做

    转回去看(T2),反复想了想,这不是以我目前实力可以解决的

    再看(T3),已经(11:00),已经放弃(T3)正解,开始思考查询做法(事实证明写了也没用
    因为只有查询,所以可以考虑离线做法,然后我脑袋一热,尝试写昨天仅仅听过一遍的莫队,然后在最后(20)分钟写出来了,又花时间对了对拍,把部分分草草合并交了

    下午查成绩
    (T1:100pts)
    (T2:30pts)
    (T3:0)
    (T4:0)

    (Tot = 100pts + 30pts + 0pts+0pts)

    (T3)挂了 (?!?!) 我对拍了呀
    讲评的时候我才知道,(30)分取模出现负数了,没有修成正数,挂了
    莫队就更惨了,所有询问做法全部是在大于(1e5)的范围内进行的,(O(nsqrt n))过不去……

    莫队

    一种离线算法,被称为“优雅的暴力”
    正常莫队不支持修改,且要求支持(O(1))快速单点插入、删除

    先对所有询问按照左端点分块,对所有询问先按左端点所在的块排序,再按照右端点排序,
    然后对每个询问,移动左右指针,并维护当前区间信息,移动指针时要求进行(O(1))不断更新信息

    代码

    lagrange代码,显然提交它并不会得分,但毕竟跑的更快一点点

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    
    using namespace std;
    
    #define mod  998244353
    #define int long long 
    
    const int p=5e5+5;
    
    struct node{
    	int x,y;
    };
    
    struct qry{
    	int l,r;
    	int place;
    	int id;
    };
    
    qry query[p];
    node mum[p];
    int suma;
    int sumb;
    int sumx;
    int n;
    int q;
    inline bool cmp(qry a,qry b)
    {
    	if(a.place != b.place)
    	return a.place < b.place;
    	else
    	{
    		return a.r < b.r;
    	}
    }
    
    int l=1,r = 0;
    
    inline int sum(int point)
    {
    	
    	suma += mum[point].x*mum[point].x;
    	suma%=mod;
    	sumb += mum[point].y*mum[point].y;
    	sumb%=mod;
    	sumx += 2*(mum[point].x*mum[point].y)%mod;
    	sumx%=mod;
    }
    
    inline int arcsum(int point)
    {
    	
    	suma -= mum[point].x*mum[point].x;
    	suma %= mod;
    	sumb -= mum[point].y*mum[point].y;
    	sumb %= mod;
    	sumx -= 2*(mum[point].x*mum[point].y%mod);
    	sumx %= mod;
    }
    
    int ans[p];
    
    inline int addrj(int point)
    {
    	int aux=0;
    	
    	if(l== r) 
    	{
    		return 0;
    	}
    	aux += (suma*(mum[point].y*mum[point].y%mod)% mod)%mod;
    	aux -= (sumx*(mum[point].x * mum[point].y%mod)%mod)%mod;
    	aux += (sumb*(mum[point].x*mum[point].x%mod)%mod)%mod;
    	
    	return (aux%mod);
    }
    
    inline void solve()
    {
    	int now = 0;
    	
    	for(int i=1;i<=q;i++)
    	{
    		int ql = query[i].l , qr = query[i].r;
    		
    		
    		while(r < qr) r++,now += addrj(r),now%=mod,sum(r);
    		while(r > qr) arcsum(r),now -= addrj(r),now%=mod,r--;
    		while(l < ql) arcsum(l),now -= addrj(l),now%=mod,l++;
    		while(l > ql) l--,now += addrj(l),now%=mod,sum(l);
    		
    		ans[query[i].id] = (now+mod)%mod;
    	}
    }
    
    signed main()
    {
    	ios_base::sync_with_stdio(false);
    	cout.tie(NULL);
    	cin.tie(NULL);
    	
    	cin>>n>>q;
    	
    	const int T=sqrt(n);
    	
    	for(int i=1;i<=n;i++)
    	{
    		cin>>mum[i].x;
    	}
    	
    	for(int i=1;i<=n;i++)
    	{
    		cin>>mum[i].y;
    	}
    	
    	for(int i=1,op;i<=q;i++)
    	{
    		cin>>op;
    		if(op == 1)
    		{
    			cin>>query[i].l;
    			query[i].place = (query[i].l+1)/T;
    			cin>>query[i].r;
    			query[i].id = i;
    		}
    	}
    	
    	sort(query+1,query+1+q,cmp);
    	
    	solve();
    	
    	for(int i=1;i<=q;i++) cout<<ans[i]<<endl;
     } 
     
    
  • 相关阅读:
    C#.NET Split 的几种使用方法
    给网站指明手机网网站
    手机访问网站自动跳转到手机版
    手机网页点击链接触发手机自动拨打或保存电话的代码
    图片切换效果2(定时+左右按钮)
    java HttpClient设置代理
    将应用部署到Tomcat根目录的方法
    Java中ArrayList类的用法
    JSP/Serlet 使用fileupload上传文件
    java 格式化字符串
  • 原文地址:https://www.cnblogs.com/-Iris-/p/13775479.html
Copyright © 2011-2022 走看看