P1006: a line segment tree without lazy.
The idea is latency mark.
#include<stdio.h>#include<algorithm>#include<string.h>#include<math.h>#include<iostream>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define N 111111typedef long long ll;ll a[N*4],add[N*4];int n;int gcd(int a,int b){ if (a%b==0) return b; return gcd(b,a%b);}void build(int l,int r,int rt){ add[rt]=0; if (l==r) { scanf("%d",&a[rt]); return; } int m=(l+r)>>1; build(lson); build(rson);}void pushdown(int rt){ if (add[rt]) { add[rt<<1]=add[rt<<1|1]=add[rt]; a[rt<<1]=a[rt<<1|1]=a[rt]; add[rt]=0; }}void update1(int L,int R,int l,int r,int rt,int x){ if (L<=l&&R>=r) { add[rt]=1; a[rt]=x; return; } pushdown(rt); int m=(l+r)>>1; if (L<=m) update1(L,R,lson,x); if (R>m) update1(L,R,rson,x); }void update2(int L,int R,int l,int r,int rt,int x){ if (add[rt]&&L<=l&&R>=r) { if (a[rt]>x) a[rt]=gcd(a[rt],x); return; } if (l==r) { if (a[rt]>x) a[rt]=gcd(a[rt],x); return ; } pushdown(rt); int m=(l+r)>>1; if (L<=m) update2(L,R,lson,x); if (R>m) update2(L,R,rson,x);}int query(int x,int l,int r,int rt){ if (l==r) return a[rt]; int m=(l+r)>>1; pushdown(rt); if (x<=m) return query(x,lson); else if (x>m) return query(x,rson);}int main(){ int T; scanf("%d",&T); while (T--){ scanf("%d",&n); build(1,n,1); int Q; scanf("%d",&Q); while (Q--) { int t,l,r,x; scanf("%d%d%d%d",&t,&l,&r,&x); if (t==1) update1(l,r,1,n,1,x); else update2(l,r,1,n,1,x); } for (int i=1;i<=n;i++) printf("%d ",query(i,1,n,1)); printf("\n"); }return 0;}View code
P1005: Status DP has not been called,
It turns out that there is a mod operation in the equation, and then there is a negative when the subtraction occurs, Nima is going crazy.
# Include <stdio. h> # include <algorithm> # include <string. h> # include <math. h> typedef long ll; using namespace STD; # define mod limit 7ll L [1234] [1124], R [1234] [1124]; int A [1234]; int N; int main () {int t; scanf ("% d", & T); While (t --) {scanf ("% d", & N); memset (L, 0, sizeof (l); memset (R, 0, sizeof (R); For (INT I = 1; I <= N; I ++) scanf ("% d", & A [I]); // records the statuses on both sides of the For (INT I = N; I> = 1; I --) {R [I] [A [I] ++; For (Int J = 0; j <1024; j ++) if (R [I + 1] [J]) {R [I] [J] + = R [I + 1] [J]; if (R [I] [J]> mod) R [I] [J]-= MOD; R [I] [J & A [I] + = R [I + 1] [J]; if (R [I] [J & A [I]> mod) R [I] [J & A [I]-= MOD ;}} for (INT I = 1; I <= N; I ++) {L [I] [A [I] ++; For (Int J = 0; j <1024; j ++) if (L [I-1] [J]) {L [I] [J] + = L [I-1] [J]; if (L [I] [J]> mod) L [I] [J]-= MOD; L [I] [J ^ A [I] + = L [I-1] [J]; If (L [I] [J ^ A [I]> mod) L [I] [J ^ A [I]-= mod ;}} ll ans = 0; For (INT I = 1; I <n; I ++) for (Int J = 0; j <1024; j ++) {ll OK = L [I] [J]-l [I-1] [J]; // The most important step is to ensure that the first I has been selected, and then match the right with if (OK <0) OK + = MOD; If () OK = OK * R [I + 1] [J] % MOD; ans + = OK; If (ANS> mod) ans-= MOD ;} printf ("% i64d \ n", ANS );}}View code