您的位置:首页 > 其它

cug1702&&CCNU校赛J题 分块

2016-05-19 23:28 267 查看
题目大意:




思路:平方分割,区间更新是用lazy标记,需要时更新。这个需要不仅仅是在query是需要,update时也可能需要,如处理两端的时候就需要。标记的同事需要记录每次的p , q , r , s对a[i],b[i]的影响,相当于维护一个二维矩阵的值,这里就不推了,写一遍就知道了,一个简单的代换。还有一个就是对2^32取模,直接无符号整形即可。做的时候因为solve函数没写好,还有一些边界问题错了好多。。。时限2s,跑了1s7刚刚卡过去…………很水

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <iomanip>

using namespace std;
//#pragma comment(linker, "/STACK:102400000,102400000")
#define maxn 100050
#define MOD 1000000007
#define mem(a , b) memset(a , b , sizeof(a))
#define LL long long
#define ULL unsigned long long
#define FOR(i , n) for(int i = 1 ;  i<= n ; i ++)
typedef pair<int , int> pii;
const long long INF= 0x3fffffff;
int n , m;
int  dis ;
unsigned int a[maxn] , b[maxn];
unsigned int p[maxn];
unsigned int tmp1 , tmp2;
struct node
{
unsigned int ra ,sa , rb , sb , val;
}flag[maxn];

unsigned int solve(int x)
{
int l = x * dis;
int r = (x + 1) * dis ;
unsigned ans = 0;
for(int i = l ; i < r && i <= n; i ++)
{
tmp1 = a[i] , tmp2 = b[i];
a[i] = tmp1 * flag[x].ra + tmp2 * flag[x].sa;
b[i] = tmp1 * flag[x].rb + tmp2 * flag[x].sb;
ans += (a[i] * b[i]);
}
flag[x].val = 0;
return p[x] = ans;
}

unsigned int get(int x)
{
int l = x * dis;
int r = (x + 1) * dis ;
unsigned int ans = 0;
for(int i = l ; i < r && i <= n; i ++)
{
ans += (a[i] * b[i]);
}
return  ans;
}

void update(int l , int r , unsigned int ra , unsigned int sa , unsigned int rb , unsigned int sb)
{
int st = (l)/dis ;
int ed = (r)/dis ;
for(int i = st+1 ; i < ed ; i ++)
{
if(!flag[i].val)
{
flag[i].ra = ra;
flag[i].sa = sa;
flag[i].rb = rb;
flag[i].sb = sb;
flag[i].val = 1;
}
else
{
unsigned int t1 = flag[i].ra , t2 = flag[i].sa , t3 = flag[i].rb , t4 = flag[i].sb;
flag[i].ra = (t1*ra + t3*sa);
flag[i].rb = (t1*rb + t3*sb);
flag[i].sa = (t2*ra + t4*sa);
flag[i].sb = (t2*rb + t4*sb);
}
}
if(flag[st].val) solve(st);
if(st != ed && flag[ed].val) solve(ed);
int up = (st+1)*dis;
for(int i = l ; i < up && i <= r; i ++)
{
tmp1 = a[i] , tmp2 = b[i];
a[i] = tmp1 * ra + tmp2 * sa;
b[i] = tmp1 * rb + tmp2 * sb;
}
p[st] = get(st);
if(st == ed) return;
for(int i = ed*dis ; i <= r ; i ++)
{
tmp1 = a[i] , tmp2 = b[i];
a[i] = tmp1 * ra + tmp2 * sa;
b[i] = tmp1 * rb + tmp2 * sb;
}
p[ed] = get(ed);
}

unsigned int query(int l , int r)
{
int st = (l)/dis ;
int ed = (r)/dis ;
unsigned int ans = 0;
for(int i = st+1 ; i < ed ; i ++)
{
if(flag[i].val)
{
ans += solve(i);
}
else ans += p[i];
}
if(flag[st].val) solve(st);
if(st != ed && flag[ed].val) solve(ed);
int up = (st+1)*dis;
for(int i = l ; i < up && i <= r; i ++)
{
ans += (a[i] * b[i]);
}
if(st == ed) return ans;
for(int i = ed*dis ; i <= r ; i ++)
{
ans += (a[i] * b[i]);
}
return ans ;
}

int main()
{
// freopen("D:\\J.in", "r", stdin);
// freopen("D:\\ss.out", "w", stdout);

while(scanf("%d %d" , &n , &m) != EOF)
{
mem(p , 0) ; mem(flag , 0);mem(a ,0) ; mem(b , 0);
dis = (int)sqrt(1.0*n);
for(int i = 1 ; i <= n ; i ++)
scanf("%u" , &a[i]);
for(int i = 1 ; i <= n ; i ++)
scanf("%u" , &b[i]);
for(int i = 1 ; i <= n ; i ++)
{
p[(int)(i/dis)] += a[i]*b[i];
}
while(m--)
{
int op , x , y ;
unsigned int  ra , sa , rb , sb;
scanf("%d" , &op);
if(op == 1)
{
scanf("%d %d %u %u %u %u" ,&x , &y , &ra , &sa , &rb , &sb);
update(x , y , ra  ,sa , rb , sb);
}
else
{
scanf("%d %d" , &x , &y);
printf("%u\n" , query(x , y));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: