• 李超树学习记录


    还没更完

    引子

    本文是按照李超老师的线段树ppt学习的学习记录以及一些心得

    cf145E

    题意

    两个操作:
    1.翻转([l,r])中的0和1
    2.求([l,r])的最长不下降子序列长度

    思路

    线段树维护00,01,10,11的长度,翻转就是交换(00,11)和(01,10)
    答案就是max(00-00,00-01,00-11,01-11,11-11)

    代码

    Code
    
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    

    define fst first

    define sc second

    define pb push_back

    define mem(a,b) memset(a,b,sizeof(a))

    define lson l,mid,root<<1

    define rson mid+1,r,root<<1|1

    define lc root<<1

    define rc root<<1|1

    define lowbit(x) ((x)&(-x))

    using namespace std;

    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;

    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 1e6+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);

    int len00[maxn<<2],len01[maxn<<2],len11[maxn<<2],len10[maxn<<2];
    int flg[maxn<<2];
    int a[maxn];
    int n,m;
    void pushup(int l, int r, int root){
    int mid = (l+r)>>1;
    len00[root]=len00[lc]+len00[rc];
    len01[root]=max(len00[lc]+max(len01[rc],len11[rc]),len01[lc]+len11[rc]);
    len10[root]=max(len11[lc]+max(len10[rc],len00[rc]),len10[lc]+len00[rc]);
    len11[root]=len11[lc]+len11[rc];
    return;
    }
    void build(int l, int r, int root){
    int mid = (l+r)>>1;
    if(lr){
    if(a[l])len11[root]=1;
    else len00[root]=1;
    return;
    }
    build(lson);build(rson);
    pushup(l,r,root);
    return;
    }
    void pushdown(int l, int r, int root){
    int mid = (l+r)>>1;
    if(flg[root]){
    flg[lc]^=1;flg[rc]^=1;
    flg[root]^=1;
    swap(len00[lc],len11[lc]);swap(len00[rc],len11[rc]);
    swap(len01[lc],len10[lc]);swap(len01[rc],len10[rc]);
    }
    }
    void update(int x, int y, int l, int r, int root){
    int mid = (l+r)>>1;
    if(x<=l&&r<=y){
    flg[root]^=1;
    swap(len00[root],len11[root]);
    swap(len01[root],len10[root]);
    return;
    }
    pushdown(l,r,root);
    if(x<=mid)update(x,y,lson);
    if(mid<y)update(x,y,rson);
    pushup(l,r,root);
    return;
    }
    void gao(int l, int r, int root){
    int mid = (l+r)>>1;
    if(l
    r)return;
    pushdown(l,r,root);
    gao(lson);gao(rson);
    return;
    }
    int main() {
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++){
    scanf("%1d", &a[i]);
    a[i]=(a[i]4?0:1);
    }
    build(1,n,1);
    for(int i = 1; i <= m; i++){
    char op[66];
    scanf("%s",op+1);
    if(op[1]
    's'){
    int l, r;
    scanf("%d %d", &l, &r);
    update(l,r,1,n,1);
    }
    else{
    int ans = 0;
    ans=max(ans,len11[1]);
    ans=max(ans,len01[1]);
    ans=max(ans,len00[1]);
    printf("%d ",ans);
    }
    }
    return 0;
    }

    ##BZOJ1103 ###题意 一棵树,初始每条边都是1,两个操作: 1.将某个边改为0 2.问一个点到根的边权和 ###思路 ####法一 线段树维护dfs序,操作1为区间修改,操作2为单点查询 这题10s时限,加了快读跑了9s。。 ####代码
    Code
    
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    

    define fst first

    define sc second

    define pb push_back

    define mem(a,b) memset(a,b,sizeof(a))

    define lson l,mid,root<<1

    define rson mid+1,r,root<<1|1

    define lc root<<1

    define rc root<<1|1

    define lowbit(x) ((x)&(-x))

    using namespace std;

    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;

    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 3e5+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);

    inline int read(){
    int num;
    char ch;
    while((ch=getchar())<'0' || ch>'9');
    num=ch-'0';
    while((ch=getchar())>='0' && ch<='9'){
    num=num*10+ch-'0';
    }
    return num;
    }

    vectorv[maxn];
    int n,q;
    int S[maxn];
    int bg[maxn],ed[maxn];
    int tot;
    int a[maxn];
    void dfs(int x, int fa, int cnt){
    S[++tot]=x;
    bg[x]=tot;
    a[tot]=cnt;
    for(int i = 0; i < (int)v[x].size(); i++){
    int y = v[x][i];
    if(yfa)continue;
    dfs(y,x,cnt+1);
    }
    ed[x]=tot;
    }
    int sum[maxn<<2],addv[maxn<<2];
    void build(int l, int r, int root){
    int mid = (l+r)>>1;
    if(l
    r){
    sum[root]=a[l];
    return;
    }
    build(lson);build(rson);
    sum[root]=sum[lc]+sum[rc];
    return;
    }
    void pushdown(int l, int r, int root){
    int mid = (l+r)>>1;
    if(addv[root]!=0){
    addv[lc]+=addv[root];
    addv[rc]+=addv[root];
    sum[lc]+=(mid-l+1)addv[root];
    sum[rc]+=(r-mid)
    addv[root];
    addv[root]=0;
    }
    }
    void update(int x, int y, int add, int l, int r, int root){
    int mid = (l+r)>>1;
    if(x<=l&&r<=y){
    addv[root]+=add;
    sum[root]+=add*(r-l+1);
    return;
    }
    pushdown(l,r,root);
    if(x<=mid)update(x,y,add,lson);
    if(y>mid)update(x,y,add,rson);
    sum[root]=sum[lc]+sum[rc];
    return;
    }
    int ask(int l, int r, int root, int x){
    int mid = (l+r)>>1;
    if(l==r)return sum[root];
    pushdown(l,r,root);
    if(x<=mid)return ask(lson,x);
    else return ask(rson,x);
    }

    int main(){
    n=read();
    tot = 0;
    for(int i = 1; i < n; i++){
    int x, y;
    x=read();y=read();
    v[x].pb(y);v[y].pb(x);
    }
    dfs(1,-1,0);
    build(1,n,1);
    scanf("%d", &q);
    for(int i = 1; i < q+n; i++){
    char op[5];
    int x, y;
    scanf("%s",op+1);
    if(op[1]=='W'){
    x=read();
    //scanf("%d", &x);
    printf("%d ",ask(1,n,1,bg[x]));
    }
    else{
    x=read();y=read();
    //scanf("%d %d", &x ,&y);
    if(x>y)swap(x,y);
    update(bg[y],ed[y],-1,1,n,1);
    }
    }
    return 0;
    }

    ####法二 建欧拉序,进入的权值为1,退出的权值为-1 操作1为修改进入和退出的权值为0 操作2为查询前缀和 树状数组即可 跑了5s ####代码
    Code
    
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    

    define fst first

    define sc second

    define pb push_back

    define mem(a,b) memset(a,b,sizeof(a))

    define lson l,mid,root<<1

    define rson mid+1,r,root<<1|1

    define lc root<<1

    define rc root<<1|1

    using namespace std;

    typedef double db;
    typedef long double ldb;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> PI;
    typedef pair<ll,ll> PLL;

    const db eps = 1e-6;
    const int mod = 1e9+7;
    const int maxn = 8e5+100;
    const int maxm = 2e6+100;
    const int inf = 0x3f3f3f3f;
    const db pi = acos(-1.0);

    inline int read(){
    int num;
    char ch;
    while((ch=getchar())<'0' || ch>'9');
    num=ch-'0';
    while((ch=getchar())>='0' && ch<='9'){
    num=num*10+ch-'0';
    }
    return num;
    }

    int lowbit(int x){
    return x&-x;
    }
    int n,q;
    int tot;
    int tree[maxn<<2];
    void add(int x,int C){
    //printf("add %d %d ",x,C);
    for(int i=x;i<=tot;i+=lowbit(i)){
    tree[i]+=C;
    }
    }
    int sum(int x){
    int ans=0;
    //printf("
    sum %d ",x);
    for(int i=x;i;i-=lowbit(i)){
    ans+=tree[i];
    }
    return ans;
    }

    vectorv[maxn];
    int S[maxn];
    int bg[maxn],ed[maxn];
    int a[maxn];
    void dfs(int x, int fa, int cnt){
    S[++tot]=x;
    bg[x]=tot;
    a[tot]=1;
    for(int i = 0; i < (int)v[x].size(); i++){
    int y = v[x][i];
    if(y==fa)continue;
    dfs(y,x,cnt+1);
    }
    S[++tot]=x;
    a[tot]=-1;
    ed[x]=tot;
    }

    int main(){
    n=read();
    tot = 0;
    for(int i = 1; i < n; i++){
    int x, y;
    x=read();y=read();
    v[x].pb(y);v[y].pb(x);
    }
    dfs(1,-1,0);
    for(int i = 1; i <= n; i++){
    add(bg[i],1);add(ed[i],-1);
    }
    scanf("%d", &q);
    for(int i = 1; i < q+n; i++){
    char op[5];
    int x, y;
    scanf("%s",op+1);
    if(op[1]=='W'){
    x=read();
    printf("%d ",sum(bg[x])-1);
    }
    else{
    x=read();y=read();
    if(x>y)swap(x,y);
    add(bg[y],-1);add(ed[y],1);
    }
    }
    return 0;
    }

    Code
    
    

  • 相关阅读:
    MySQL乱码问题
    Oracle安装错误“程序异常终止
    Hibernate Spring
    快学Scala 第一课 (变量,类型,操作符)
    Scala 学习笔记之隐式参数和隐式转换并用
    Hadoop 学习笔记之 Incompatible namespaceIDs问题
    Kafka 学习笔记之 Topic日志清理
    Zookeeper 学习笔记之 节点个数
    Kafka 学习笔记之 删除Topic
    Kafka 学习笔记之 架构
  • 原文地址:https://www.cnblogs.com/wrjlinkkkkkk/p/11515350.html
Copyright © 2020-2023  润新知