【JZOJ5270】【GDOI2018模拟】神奇的矩阵(二维线段树)
2017-08-23 07:49
381 查看
Description
Solution
这题直接三方log只有70分,想要打的更好只能打平方log方的,那么很显然就是用一个二维的数据结构来维护。这还是我第一次打二维线段树(不是线段树套线段树)
首先我们对于绝对值可以考虑小的数被贡献多少次,那么就是找大的数的和-小的数的出现次数,那么我们就可以考虑把所有的数从小到大排序然后依次插入。
然后每个点上统计一个以它为左上角的矩阵可以被贡献多少次,那么每次插进一个数,就把它左上角的矩阵全部都加上a[i],然后询问的时候也是询问左上角的矩阵,左上角的矩阵。(注意要先询问再修改),这样意义其实就是以一个点为左上角的矩阵包括的数集一一与刚插进来的数匹配。
用线段树修改和询问的区间都是同一个区间,那么可以打在一起。
Code
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #define fo(i,a,b) for(i=a;i<=b;i++) typedef long long ll; using namespace std; const ll maxn=507,mo=1e4+7; ll i,j,k,l,n,m,ans,tot,yi,er; ll a[maxn][maxn]; struct nod{ ll x,y,z; }b[maxn*maxn]; struct node{ ll sum,num,bz1,bz2; }t[maxn*maxn*80]; bool cmp(nod x,nod y){return x.z<y.z;} void down(ll x,ll l,ll r,ll l1,ll r1){ ll mid=(l+r)/2; if(t[x].bz1){ t[x*2].sum+=t[x].bz1*(r1-l1+1)*(mid-l+1)%mo;t[x*2+1].sum+=t[x].bz1*(r1-l1+1)*(r-mid)%mo; t[x*2].num+=t[x].bz2*(r1-l1+1)*(mid-l+1);t[x*2+1].num+=t[x].bz2*(r1-l1+1)*(r-mid); t[x*2].bz1+=t[x].bz1;t[x*2+1].bz1+=t[x].bz1; t[x*2].bz2+=t[x].bz2;t[x*2+1].bz2+=t[x].bz2; t[x].bz1=t[x].bz2=0; } } void change(ll x,ll l,ll r,ll l1,ll r1,ll y,ll z,ll yy,ll zz,ll o){ if(l>=y&&r<=z&&l1>=yy&&r1<=zz){ yi+=t[x].sum;er+=t[x].num; t[x].sum+=(r1-l1+1)*(r-l+1)*o%mo;t[x].num+=(r1-l1+1)*(r-l+1); t[x].bz1+=o,t[x].bz2++; return; } down(x,l,r,l1,r1); ll mid=(l+r)/2; if(z<=mid)change(x*2,l1,r1,l,mid,yy,zz,y,z,o); else if(y>mid)change(x*2+1,l1,r1,mid+1,r,yy,zz,y,z,o); else change(x*2,l1,r1,l,mid,yy,zz,y,mid,o),change(x*2+1,l1,r1,mid+1,r,yy,zz,mid+1,z,o); t[x].sum=t[x*2].sum+t[x*2+1].sum; t[x].num=t[x*2].num+t[x*2+1].num; } int main(){ freopen("matrix.in","r",stdin); freopen("matrix.out","w",stdout); scanf("%lld%lld%lld",&n,&m,&k); fo(i,1,n)fo(j,1,m)scanf("%lld",&a[i][j]),b[++tot].x=i,b[tot].y=j,b[tot].z=a[i][j]; sort(b+1,b+tot+1,cmp); fo(l,1,tot){ yi=er=0; change(1,1,n,1,m,max(b[l].x-k+1,(ll)1),min(n-k+1,b[l].x),max(b[l].y-k+1,(ll)1),min(m-k+1,b[l].y),b[l].z); // b[l].z%=mo; ans=ans+er*b[l].z%mo-yi; } ans=(ans*2%mo+mo)%mo; printf("%lld\n",ans); }
相关文章推荐
- 【JZOJ5270】【GDOI2018模拟8.14】神奇的矩阵
- 【JZOJ5272】【GDOI2018模拟8.14】神奇的重复序列
- 【JZOJ5272】【GDOI2018模拟】神奇的重复序列(DP,性质题)
- 【jzoj5215】【BZOJ4870】【Shoi2017】【GDOI2018模拟7.9】【组合数问题】【矩阵快速幂】
- 【jzoj5223】【GDOI2018模拟7.12】【B】【矩阵乘法】
- 【GDOI2018模拟8.14】神奇的矩阵
- 【jzoj5221】【GDOI2018模拟7.10】【A】【线段树合并】
- JZOJ5242【GDOI2018模拟8.8】矩阵
- 【JZOJ5250】【GDOI2018模拟8.11】质数
- 【JZOJ5260】【GDOI2018模拟8.12】区间第k小(分块)
- 【JZOJ 5239】 【GDOI2018模拟8.7】图的异或
- 【jzoj5250】【GDOI2018模拟8.11】【质数】
- 【JZOJ5219】【GDOI2018模拟7.10】B
- 【JZOJ5262】【GDOI2018模拟8.12】树(DP,性质题)
- 【jozj5228】【GDOI2018模拟7.14】【小奇的集合】【矩阵乘法】
- 【JZOJ 5229】【GDOI2018模拟7.14】小奇的糖果
- 【JZOJ 5250】【GDOI2018模拟8.11】质数
- 【jzoj5239】【GDOI2018模拟8.7】【图的异或】【线性基】
- jzoj5220 【GDOI2018模拟7.10】C (双序列dp)
- 【JZOJ5220】【GDOI2018模拟7.10】C