首页 > 其他分享 >P4036 [JSOI2008] 火星人

P4036 [JSOI2008] 火星人

时间:2024-09-24 20:23:17浏览次数:1  
标签:火星人 P4036 int JSOI2008 retl retr second split first

#include <bits/stdc++.h>
#define int long long
using namespace std;
int len;
int m;
int rt = 0;
int has[1000010];
void init()
{
	srand(1);
    has[0] = 1;
    for(int i = 1;i <= 1000000;i++)
        has[i] = has[i - 1] * 101;
    //cout << has[] << endl;
}
char s[1000010];
struct edge
{
    int val;
	int lson;
	int s;
	int rson;
    int kth;
    int siz;
}e[1000010];
int cnt = 0;
int newnode(int xx)
{
    e[++cnt].val = xx;
    e[cnt].kth = rand();
    e[cnt].s = xx;
    e[cnt].siz = 1;
    return cnt;
}
void up(int x)
{
	e[x].siz = e[e[x].lson].siz + e[e[x].rson].siz + 1;
    e[x].s = e[e[x].lson].s * has[e[e[x].rson].siz + 1] + e[x].val * has[e[e[x].rson].siz] + e[e[x].rson].s;
}
int merge(int A,int B)
{
	///cout << A << " " << B << endl;
    if(!A || !B)return A + B;
    if(e[A].kth < e[B].kth)
    {
        e[A].rson = merge(e[A].rson,B);
        up(A);
        return A;
    }
    else
    {
        e[B].lson = merge(A,e[B].lson);
        up(B);
        return B;
    }
}
pair<int,int> split(int x,int val)
{
    if(!x)return pair<int,int>();
    ///cout << x << endl;
    if(val <= e[e[x].lson].siz)
    {
        pair<int,int> s = split(e[x].lson,val);
        e[x].lson = s.second;
        s.second = x;
        up(x);
        return s;
    }
    else
    {
        pair<int,int> s = split(e[x].rson,val - e[e[x].lson].siz - 1);
        e[x].rson = s.first;
        s.first = x;
        up(x);
        return s;
       /* for(int i = 1;i <= len;i++)
        {
        	printf("%d",f[i]); 
		}*/
    }
}
int Has(int L,int R)
{
    if(L > R)return 0;
    pair<int,int> retl = split(rt,R);
    pair<int,int> retr = split(retl.first,L - 1);
    int res = e[retr.second].s;
    retl.first = merge(retr.first,retr.second);
    rt = merge(retl.first,retl.second);
    ///cout << L << " " << R << endl;
    return res;
}
void add(int x,int val)
{
    pair<int,int> retl = split(rt,x);
    retl.first = merge(retl.first,newnode(val));
    rt = merge(retl.first,retl.second);
    len++;
}
int query(int x,int y)
{
    int l = 0,r = min(len - x + 1,len - y + 1);
    while(l < r)
    {
    	//cout << l << " " << r << endl;
        int mid = (l + r + 1) / 2;
        if(Has(x,x + mid - 1) == Has(y,y + mid - 1))l = mid;
        else r = mid - 1;
    }
    return l;
}
void updata1(int x,int val)
{
    pair<int,int> retl = split(rt,x);
    pair<int,int> retr = split(retl.first,x - 1);
    e[retr.second].s = e[retr.second].val = val;
    retl.first = merge(retr.first,retr.second);
    rt = merge(retl.first,retl.second);
}
signed main()
{
	init();
	int x,y;
    scanf("%s",s + 1);
	scanf("%lld",&m);
    len = strlen(s + 1);
    for(int i = 1;i <= len;i++)
        rt = merge(rt,newnode(s[i] - 'a' + 1));
    for(int i = 1;i <= m;i++)
    {
        scanf("%s",s + 1);
        if(s[1] == 'Q')
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(x,y));
        }
        else if(s[1] == 'R')
        {
            scanf("%lld%s",&x,s + 1);
            updata1(x,s[1] - 'a' + 1);
        }
        else
        {
            scanf("%lld %s",&x,s + 1);
            add(x,s[1] - 'a' + 1);
        }
    }
    return 0;
}

标签:火星人,P4036,int,JSOI2008,retl,retr,second,split,first
From: https://www.cnblogs.com/xyjkanade/p/18429941

相关文章

  • 火星人集成灶F59说明书
     官网电话:4008888490                   aa......
  • C130 并查集 P1197 [JSOI2008] 星球大战
    视频链接:  P1197[JSOI2008]星球大战-洛谷|计算机科学教育新生态(luogu.com.cn)//并查集#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintN=400005;inth[N],from[N],to[N],ne[N],idx;voidadd(intu,intv){from[......
  • P1197 [JSOI2008] 星球大战
    原题链接题解,请看题解区第一篇,看一遍就会了code#include<bits/stdc++.h>usingnamespacestd;intfa[400005]={0};intfinds(intnow){returnfa[now]=(fa[now]==now?now:finds(fa[now]));}vector<int>G[400005];intbroke[400005];intBroke[400005]={0};intm......
  • P1088 [NOIP2004 普及组] 火星人
    [NOIP2004普及组]火星人题目描述人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小......
  • P1198 [JSOI2008] 最大数
    原题链接题解1:单调栈+并查集?单调栈特性:栈内元素大小和序号由栈底到栈顶具有单调性,本题大小单调减,序号单调增维护:新元素入栈时,栈内剩余的所有小于该元素的元素出栈,并视新元素为集合首领,然后新元素入栈查询:查询集合首领即可code1#definelllonglong#include<bits/stdc++.h>......
  • 洛谷题单指南-暴力枚举-P1088 [NOIP2004 普及组] 火星人
    原题链接:https://www.luogu.com.cn/problem/P1088题意解读:火星人的手指可以通过全排列来表示数字,全排列由小到大的顺序即为表示的数字大小,题目可以转化为:给定按顺序全排列中的某一个排列,求往后数m个排列的内容。解题思路:此题与经典全排列问题的差异在于,需要从指定一个排列开......
  • P1197 [JSOI2008] 星球大战 题解
    P1197[JSOI2008]星球大战题解题目链接P1197[JSOI2008]星球大战简要思路看完题目的第一印象是——连通性。图论中判断连通性很容易想到并查集,但是并查集只支持合并和查询,并不支持删除,怎么办呢?考虑逆向思维,把删点的过程倒过来,看成加点和连边,那么此题就可以非常方便的用并......
  • 「JSOI2008」最小生成树计数 题解报告
    简要题意现在给出了一个简单无向加权图。你希望知道这个图中有多少个不同的最小生成树。(如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的)。输出方案数对\(31011\)取模。SOLUTION这个题求最小生成树的方案所以我们从最小生成树入手(根据kruskal的思路)我们......
  • P4036 [JSOI2008] 火星人
    暴力水过了wwwwwwwwwwwwwww#include<bits/stdc++.h>//================================================//#defineLOCALFLANDREKAWAII#ifndefLOCALconstexprintSIZE(1<<20);charin[SIZE],out[SIZE],*p1=in,*p2=in,*p3=out;#definegetchar(......
  • [NOIP2004 普及组] 火星人
    题目简单,A完之后看题解,看到大佬的一片题解有感而发,这位大佬的DFS确实精妙看完题之后你会发现只需要5行就可以解决,c++自带的全排列函数,但是有位大佬手写DFS的方法非常巧妙,直接精确定位,让我对dfs的理解多多少少又加深一层题目描述人类终于登上了火星的土地并且见到了神秘......