Codeforces Round #321 (Div. 2)E 线段树+字符串hash

本文介绍了一种使用双关键字哈希与线段树解决字符串周期性检查问题的方法,通过构建线段树来高效地处理字符串修改及周期性验证查询。

E. Kefa and Watch
time limit per test1.5 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
One day Kefa the parrot was walking down the street as he was on the way home from the restaurant when he saw something glittering by the road. As he came nearer he understood that it was a watch. He decided to take it to the pawnbroker to earn some money.

The pawnbroker said that each watch contains a serial number represented by a string of digits from 0 to 9, and the more quality checks this number passes, the higher is the value of the watch. The check is defined by three positive integers l, r and d. The watches pass a check if a substring of the serial number from l to r has period d. Sometimes the pawnbroker gets distracted and Kefa changes in some substring of the serial number all digits to c in order to increase profit from the watch.

The seller has a lot of things to do to begin with and with Kefa messing about, he gave you a task: to write a program that determines the value of the watch.

Let us remind you that number x is called a period of string s (1 ≤ x ≤ |s|), if si  =  si + x for all i from 1 to |s|  -  x.

Input
The first line of the input contains three positive integers n, m and k (1 ≤ n ≤ 105, 1 ≤ m + k ≤ 105) — the length of the serial number, the number of change made by Kefa and the number of quality checks.

The second line contains a serial number consisting of n digits.

Then m + k lines follow, containing either checks or changes.

The changes are given as 1 l r c (1 ≤ l ≤ r ≤ n, 0 ≤ c ≤ 9). That means that Kefa changed all the digits from the l-th to the r-th to be c.

The checks are given as 2 l r d (1 ≤ l ≤ r ≤ n, 1 ≤ d ≤ r - l + 1).

Output
For each check on a single line print “YES” if the watch passed it, otherwise print “NO”.

Examples
input
3 1 2
112
2 2 3 1
1 1 3 8
2 1 2 1
output
NO
YES
input
6 2 3
334934
2 2 5 2
1 4 4 3
2 1 6 3
1 2 3 8
2 3 6 1
output
NO
YES
NO
Note
In the first sample test two checks will be made. In the first one substring “12” is checked on whether or not it has period 1, so the answer is “NO”. In the second one substring “88”, is checked on whether or not it has period 1, and it has this period, so the answer is “YES”.

In the second statement test three checks will be made. The first check processes substring “3493”, which doesn’t have period 2. Before the second check the string looks as “334334”, so the answer to it is “YES”. And finally, the third check processes substring “8334”, which does not have period 1.

这个题有几个坑点
第一个就是需要双关键字hash
第二个是在线段树更新的过程中需要去掉不需要的长度
第三个是lazy在用到的时候必须进行更新
其实也不算坑点
还是自己菜吧…

#include<iostream>
#include<cstring>
#include<string>
#include<map>
using namespace std;
int mo1 = 1000000009, mo2 = 1000000007;
unsigned long long p1[100011], s1[110001], p2[110001], s2[101001];
int bas = 17;
struct qq
{
    long long z, y, chang, z1, z2, lazy;
};
qq shu[600001];
string q;
void jian(int gen, int zuo, int you)
{
    shu[gen].z = zuo;
    shu[gen].y = you;
    shu[gen].lazy = -1;
    if (zuo == you)
    {
        shu[gen].z1 = (q[zuo-1] - '0') % mo1;
        shu[gen].z2 = (q[zuo-1] - '0') % mo2;
        return;
    }
    int mid = (zuo + you) / 2;
    jian(2 * gen, zuo, mid);
    jian(2 * gen + 1, mid + 1, you);
    shu[gen].z1 = (p1[shu[2 * gen + 1].y - shu[2 * gen + 1].z +1] * shu[2 * gen].z1 + shu[2 * gen + 1].z1) % mo1;
    shu[gen].z2 = (p2[shu[2 * gen + 1].y - shu[2 * gen + 1].z +1] * shu[2 * gen].z2 + shu[2 * gen + 1].z2) % mo2;
}
void gengxin(int gen, int zuo, int you, int wz, int wy, int bian)
{
    if (zuo >= wz&&you <= wy)
    {
        shu[gen].lazy = bian;
        shu[gen].z1 = bian*s1[you - zuo] % mo1;
        shu[gen].z2 = bian*s2[you - zuo] % mo2;
        return;
    }
    else if (zuo > wy || you < wz)return;
    else
    {
        int mid = (zuo + you) / 2;
        if (shu[gen].lazy != -1)
        {
            shu[2 * gen].lazy = shu[2 * gen + 1].lazy = shu[gen].lazy;
            shu[gen].lazy = -1;
            shu[2 * gen].z1 = (shu[2 * gen].lazy*s1[shu[2 * gen].y - shu[2 * gen].z]) % mo1;
            shu[2 * gen].z2 = (shu[2 * gen].lazy*s2[shu[2 * gen].y - shu[2 * gen].z]) % mo2;
            shu[2 * gen + 1].z1 = (shu[2 * gen].lazy*s1[shu[2 * gen + 1].y - shu[2 * gen + 1].z]) % mo1;
            shu[2 * gen + 1].z2 = (shu[2 * gen].lazy*s2[shu[2 * gen + 1].y - shu[2 * gen + 1].z]) % mo2;
        }
        gengxin(2 * gen, zuo, mid, wz, wy, bian);
        gengxin(2 * gen + 1, mid + 1, you, wz, wy, bian);
        shu[gen].z1 = (p1[shu[2 * gen + 1].y - shu[2 * gen + 1].z + 1] * shu[2 * gen].z1 + shu[2 * gen + 1].z1) % mo1;
        shu[gen].z2 = (p2[shu[2 * gen + 1].y - shu[2 * gen + 1].z + 1] * shu[2 * gen].z2 + shu[2 * gen + 1].z2) % mo2;
    }
}
int flag = 0;
pair<pair<long long,long long>, long long> xunw(int gen, int zuo, int you, int wz, int wy)
{
    if (zuo > wy || you < wz)return make_pair(make_pair(-1, -1),0);
    if (zuo >= wz&&you <= wy)return make_pair(make_pair(shu[gen].z1, shu[gen].z2),you-zuo+1);
    int mid = (zuo + you) / 2;
    if (shu[gen].lazy != -1)
    {
        shu[2 * gen].lazy = shu[2 * gen + 1].lazy = shu[gen].lazy;
        shu[gen].lazy = -1;
        shu[2 * gen].z1 = (shu[2 * gen].lazy*s1[shu[2 * gen].y - shu[2 * gen].z]) % mo1;
        shu[2 * gen].z2 = (shu[2 * gen].lazy*s2[shu[2 * gen].y - shu[2 * gen].z]) % mo2;
        shu[2 * gen + 1].z1 = (shu[2 * gen].lazy*s1[shu[2 * gen + 1].y - shu[2 * gen + 1].z]) % mo1;
        shu[2 * gen + 1].z2 = (shu[2 * gen].lazy*s2[shu[2 * gen + 1].y - shu[2 * gen + 1].z]) % mo2;
    }
    pair<pair<long long, long long>, long long>zz = xunw(2 * gen, zuo, mid, wz, wy);
    pair<pair<long long, long long>, long long>yy = xunw(2 * gen + 1, mid + 1, you, wz, wy);
    if (zz.first.first == -1)return yy;
    if (yy.first.first == -1)return zz;
    int youc = yy.second;
    return make_pair(make_pair((zz.first.first*p1[youc] + yy.first.first) % mo1, (zz.first.second*p2[youc] + yy.first.second) % mo2),zz.second+yy.second);
}
int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    cin >> q;
    p1[0] = p2[0] = s1[0] = s2[0] = 1;
    for (int a = 1;a <= q.size();a++)
    {
        p1[a] = p1[a - 1] * bas%mo1;
        s1[a] = (s1[a - 1] + p1[a]) % mo1;
        p2[a] = p2[a - 1] * bas%mo2;
        s2[a] = (s2[a - 1] + p2[a]) % mo2;
    }
    int r, t, y, u;
    jian(1, 1, q.size());
    for (int a = 1;a <= m + k;a++)
    {
        scanf("%d%d%d%d", &r, &t, &y, &u);
        if (r == 1)gengxin(1, 1, q.size(), t, y, u);
        else
        {
            if (y - t + 1 == u)
            {
                cout << "YES" << endl;
                continue;
            }
            pair<pair<long long, long long>, long long> qwe = xunw(1, 1, q.size(), t, y - u);
            pair<pair<long long, long long>, long long> wer = xunw(1, 1, q.size(), t+u, y);
            if (qwe.first.first == wer.first.first&&qwe.first.second == wer.first.second)cout << "YES" << endl;
            else cout << "NO" << endl;
        }
    }
    return 0;
}
【从高压输电线的架空地线中汲取电能】一个25千瓦受控电源从735千伏线路的架空地线中汲取电能的SimPowerSystems模型(Simulink仿真实现)内容概要:本文介绍了一个基于SimPowerSystems的Simulink仿真模型,用于模拟从735千伏高压输电线的架空地线中汲取25千瓦电能的受控电源系统。该模型聚焦于高压输电线路中架空地线的能量回收技术,通过仿真手段实现对电能采集过程的建模与控制策略验证,体现了电力系统中新型能源获取方式的技术可行性与工程应用潜力。文中还提及该资源属于一系列电力系统仿真研究的一部分,涵盖微电网、储能优化、碳流追踪、鲁棒调度等多个前沿方向,配套提供Matlab/Simulink代码及网盘资料链接,便于科研人员复现与拓展研究。; 适合人群:具备电力系统基础知识、熟悉Matlab/Simulink仿真环境,从事电力工程、能源回收或智能电网相关研究的科研人员及研究生;有一定编程与建模仿真经验的高年级本科生或工程技术人员。; 使用场景及目标:①研究高压输电线路中架空地线的能量回收机制与建模方法;②掌握基于Simulink的电力系统仿真技术,特别是受控电源与电网交互的动态特性分析;③为开展能源 harvesting、分布式供能、电力电子变换器控制等相关课题提供参考模型与技术支撑; 阅读建议:建议结合提供的仿真模型文件进行实操演练,重点理解系统结构设计、参数设置与控制逻辑实现;同时可延伸学习文档中提到的其他电力系统优化与仿真案例,以拓宽研究视野和技术积累。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值