test 三角形 (乱搞)

来源:互联网 发布:java上线项目 编辑:程序博客网 时间:2024/05/18 23:52



题解:乱搞

这个题测试的时候写的线段树区间修改区间查询,然后get到50分。。。。

这个题的正解其实就是个乱搞。

每一个修改对每一个询问的影响可以O(1)的计算,需要判断两个三角形的位置关系,然后计算重叠部分的点数。

然后我们可以对每个修改进行差分,当累积的未处理的操作数达到一定值的时候,我们就将每个位置的数查询出来,然后记录到前缀和数组中,每次这么做的时间复杂度是O(n^2)

然后每次查询的时候只需要查询前缀和数组,然后再o(1)计算未加入前缀和的修改对当前询问的影响即可。

时间复杂度O(q/k*(n^2)+q*k) 当k=1000的时候就可以通过了。

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#define N 1003#define LL long longusing namespace std;LL sum[N][N],ch[N][N];int n,m,posx[N*100],posy[N*100],a1[N*100];void change(int x,int y,int a){for (int i=x;i<=x+a-1;i++){int y1=y+i-x;ch[i][y]++; ch[i][y1+1]--;}}void build(){memset(sum,0,sizeof(sum));for (int i=1;i<=n;i++) { LL t=0; for (int j=1;j<=i;j++) t+=ch[i][j],sum[i][j]=sum[i][j-1]+t; }}int main(){   freopen("delta.in","r",stdin);   freopen("delta.out","w",stdout);   scanf("%d%d",&n,&m);   int k=0; int x1,y1,x2,y2;   for (int i=1;i<=m;i++){    int opt,x,y,a; scanf("%d%d%d%d",&opt,&x,&y,&a);    if (opt==1) {      k++; posx[k]=x; posy[k]=y; a1[k]=a; change(x,y,a);      if (k==1000)  build(),k=0;} else { LL ans=0; for (int j=x;j<=x+a-1;j++) ans+=sum[j][y+j-x]-sum[j][y-1]; for (int j=1;j<=k;j++){ if (posy[j]==y&&x<posx[j]||y<posy[j]) { x1=x; y1=y;  x2=posx[j]; y2=posy[j]; }else {x1=posx[j]; y1=posy[j];x2=x; y2=y;}x2=max(x2,x1+y2-y1);int len=max(min(x+a,posx[j]+a1[j])-x2,0);ans+=(LL)(len+1)*(LL)len/2; }printf("%I64d\n",ans); }   }}


0 0
原创粉丝点击