首页 > 代码库 > 多校第四场

多校第四场

P1006:真不会线段树,更不会带LAZY的线段树。

思想就是延迟标记

#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:状态DP一直没调出来,

原来方程里有个MOD操作,然后相减时出现负的,尼玛快疯了。

#include<stdio.h>#include<algorithm>#include<string.h>#include<math.h>typedef long long ll;using namespace std;#define mod 1000000007ll 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]);//分别左右两边记录状态        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];//最重要的一步,确保第I个已经选择了,然后去和右边的搭配          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