WC模拟(1.14) T3 Try to find out the wrong in the test

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/scar_lyw/article/details/80212534

Try to find out the wrong in the test

题目背景:

1.14 WC模拟T3

分析:线段树优化DP + 复杂度分析

 

终于不用打公式了,心累······

首先我们只考虑d的限制,在满足d限制的情况下,对于一个i,可行的上一个区间的端点,一定是一段连续的区间,并且,区间右端点是i,那么我们只需要预处理出left[i]表示最小的可以用于更新i的位置,显然left[i]是单增的,我们直接用一个单调队列就可以维护了。

对于c限制并不是很好处理,于是我们考虑分治,对于一段区间[l, r],我们找出其中c值最大的位置p,递归处理[l, p - 1], [p, r],单独处理最后一个区间包含p的情况。

首先比较显然的是,如果我们要求最后一个转移区间包含p,那么可以从[l, p - 1]转移的i,一定是属于[max(p, l + c[p]), r]的,然后我们来分类讨论一下。

1left[i] < li <= p - 1 + c

显然满足条件的i[l, i - c], 并且ii + 1的可行区间只相差一个i - c + 1这个位置的贡献,那么我们可以对于第一个位置在线段树中查询,然后后面的所有直接O(1)加上贡献即可

2left[i] < li > p - 1 + c

显然,满足这个条件的i的可行转移范围全部都是[l, p - 1],那么我们只需要二分出满足这个条件的区间,然后查询[l, p - 1]的答案,之后直接给可行区间打标记即可。

3l <= left[i] < p

这一段的left[i]都不能确定,所以只能直接在线段树里面查询

4left[i] >= p

显然无法转移。
乍一看这不是n2logn的吗,真的可能过?

现在我们来分析一下复杂度

首先,对于情况1,一定首先有一个log,接下来考虑会扫过多少数,显然,满足情况1的区间是[max(l + c, p), min(r, p + c - 1)],显然区间长度是小于min(p - l + 1, r - p),相当于取被p分割的区间当中长度较小的一个。显然前面的log,一共有n层,是nlogn,后面的区间长度可以通过类似于启发式合并的思想分析,也是nlogn的。

对于情况2,显然每层只有一个,所以是nlogn

对于情况3,我们可以发现,这种情况当且仅当,改点属于区间的右边部分,但是left[i],是在左边部分,那么显然这种情况对于每一个点,有且仅会出现一次,所以是nlogn

所以,总的复杂度就是O(nlogn)的,当分治到l == r时,直接更新答案,然后更新到上层区间即可。

 

Source:

/*
	created by scarlyw
*/
#include <cstdio>
#include <string>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <cmath>
#include <cctype>
#include <vector>
#include <set>
#include <queue>

inline char read() {
	static const int IN_LEN = 1024 * 1024;
	static char buf[IN_LEN], *s, *t;
	if (s == t) {
		t = (s = buf) + fread(buf, 1, IN_LEN, stdin);
		if (s == t) return -1;
	}
	return *s++;
}

///*
template<class T>
inline void R(T &x) {
	static char c;
	static bool iosig;
	for (c = read(), iosig = false; !isdigit(c); c = read()) {
		if (c == -1) return ;
		if (c == '-') iosig = true;	
	}
	for (x = 0; isdigit(c); c = read()) 
		x = ((x << 2) + x << 1) + (c ^ '0');
	if (iosig) x = -x;
}
//*/

const int OUT_LEN = 1024 * 1024;
char obuf[OUT_LEN], *oh = obuf;
inline void write_char(char c) {
	if (oh == obuf + OUT_LEN) fwrite(obuf, 1, OUT_LEN, stdout), oh = obuf;
	*oh++ = c;
}


template<class T>
inline void W(T x) {
	static int buf[30], cnt;
	if (x == 0) write_char('0');
	else {
		if (x < 0) write_char('-'), x = -x;
		for (cnt = 0; x; x /= 10) buf[++cnt] = x % 10 + 48;
		while (cnt) write_char(buf[cnt--]);
	}
}

inline void flush() {
	fwrite(obuf, 1, oh - obuf, stdout);
}

/*
template<class T>
inline void R(T &x) {
	static char c;
	static bool iosig;
	for (c = getchar(), iosig = false; !isdigit(c); c = getchar())
		if (c == '-') iosig = true;	
	for (x = 0; isdigit(c); c = getchar()) 
		x = ((x << 2) + x << 1) + (c ^ '0');
	if (iosig) x = -x;
}
//*/

const int MAXN = 1000000 + 10;
const int mod = 1000000000 + 7;

int n;
int c[MAXN], d[MAXN], left[MAXN], f[MAXN], g[MAXN];

inline void add(int &x, int t) {
    x += t, (x >= mod) ? (x -= mod) : (0);
}

struct node {
    int c_id, f, g, tag_f, tag_g;
} tree[MAXN << 2 | 1];

inline void update(int &f, int &g, int cur_f, int cur_g) {
    if (cur_f > f) f = cur_f, g = cur_g;
    else if (f == cur_f) add(g, cur_g);
}

inline void update(int k) {
    node lc = tree[k << 1], rc = tree[k << 1 | 1];
    tree[k].c_id = ((c[lc.c_id] > c[rc.c_id]) ? lc.c_id : rc.c_id);
    if (lc.f > rc.f) tree[k].f = lc.f, tree[k].g = lc.g;
    else if (lc.f == rc.f) tree[k].f = lc.f, tree[k].g = (lc.g + rc.g) % mod;
    else tree[k].f = rc.f, tree[k].g = rc.g;
}

inline void modify(int k, int f, int g) {
    update(tree[k].f, tree[k].g, f, g);
    update(tree[k].tag_f, tree[k].tag_g, f, g);
}

inline void push_down(int k) {
    if (tree[k].tag_f > -1) {
        modify(k << 1, tree[k].tag_f, tree[k].tag_g);
        modify(k << 1 | 1, tree[k].tag_f, tree[k].tag_g);
        tree[k].tag_f = -1, tree[k].tag_g = 0;
    }
}

inline void build(int k, int l, int r) {
    tree[k].tag_f = -1, tree[k].tag_g = 0;
    if (l == r) {
        tree[k].c_id = l, tree[k].f = -1, tree[k].g = 0;
        return ;
    }
    int mid = l + r >> 1;
    build(k << 1, l, mid), build(k << 1 | 1, mid + 1, r);
    update(k);
}

inline void modify(int k, int l, int r, int ql, int qr, int f, int g) {
    if (ql <= l && r <= qr) return modify(k, f, g);
    int mid = l + r >> 1;
    if (ql <= mid) modify(k << 1, l, mid, ql, qr, f, g);
    if (qr > mid) modify(k << 1 | 1, mid + 1, r, ql, qr, f, g);
}

inline void modify(int k, int l, int r, int pos, int f, int g) {
    if (l == r) return modify(k, f, g);
    int mid = l + r >> 1;
    push_down(k);
    if (pos <= mid) modify(k << 1, l, mid, pos, f, g);
    else modify(k << 1 | 1, mid + 1, r, pos, f, g);
}

inline void query(int k, int l, int r, int ql, int qr, int &f, int &g) {
    if (qr < ql) return; 
    if (ql <= l && r <= qr) return update(f, g, tree[k].f, tree[k].g);
    int mid = l + r >> 1;
    if (ql <= mid) query(k << 1, l, mid, ql, qr, f, g);
    if (qr > mid) query(k << 1 | 1, mid + 1, r, ql, qr, f, g);
}

inline void query(int k, int l, int r, int pos, int &f, int &g) {
    if (l == r) return update(f, g, tree[k].f, tree[k].g);
    int mid = l + r >> 1;
    if (pos <= mid) query(k << 1, l, mid, pos, f, g);
    else query(k << 1 | 1, mid + 1, r, pos, f, g);
    update(k);
}

inline int find(int k, int l, int r, int ql, int qr) {
    if (ql <= l && r <= qr) return tree[k].c_id;
    int mid = l + r >> 1;
    if (qr <= mid) return find(k << 1, l, mid, ql, qr);
    else if (ql > mid) return find(k << 1 | 1, mid + 1, r, ql, qr);
    else {
        int pos1 = find(k << 1, l, mid, ql, qr);
        int pos2 = find(k << 1 | 1, mid + 1, r, ql, qr);
        return (c[pos1] > c[pos2]) ? pos1 : pos2; 
    }
}

inline void read_in() {
    R(n);
    for (int i = 1; i <= n; ++i) R(c[i]), R(d[i]);
}

inline void pre_work() {
    int cur_pos = 0, head = 1, tail = 0;
    static int q[MAXN];
    for (int i = 1; i <= n; ++i) {
        while (head <= tail && d[q[tail]] >= d[i]) tail--;
        q[++tail] = i;
        int pos;
        while (head <= tail && q[head] <= cur_pos) head++;
        pos = d[q[head]];
        while (i - pos > cur_pos) {
            ++cur_pos;
            while (head <= tail && q[head] <= cur_pos) head++;
            pos = d[q[head]];
        }
        left[i] = cur_pos;
    }
    // for (int i = 1; i <= n; ++i) std::cout << left[i] << " ";
    // std::cout << '\n';
}

inline int binary(int x, int y, int val) {
    int l = x, r = y + 1;
    while (l + 1 < r) {
        int mid = l + r >> 1;
        (left[mid] < val) ? l = mid : r = mid;
    }
    // std::cout << "??" << l << '\n';
    return l;
}

inline void solve(int l, int r, int k) {
    int start = std::max(k, l + c[k]), end1 = std::min(r, k + c[k] - 1);
    int cur_f = -1, cur_g = 0, st = start;
    while (st <= end1) {
        if (left[st] >= l) break ;
        if (left[st] >= k) return ;
        if (st == start) query(1, 0, n, l, st - c[k], cur_f, cur_g);
        else update(cur_f, cur_g, f[st - c[k]], g[st - c[k]]);
        if (cur_f != -1) update(f[st], g[st], cur_f + 1, cur_g);
        ++st;
    }
    if (st > r) return ;
    if (left[st] < l) {
        int pos = binary(st, r, l);
        cur_f = -1, cur_g = 0;
        query(1, 0, n, l, k - 1, cur_f, cur_g);
        if (cur_f > -1) modify(1, 0, n, st, pos, cur_f + 1, cur_g);
        st = pos + 1;
    }
    while (st <= r) {
        if (left[st] >= k) return ;
        cur_f = -1, cur_g = 0;
        query(1, 0, n, left[st], std::min(k - 1, st - c[k]), cur_f, cur_g);
        if (cur_f > -1) update(f[st], g[st], cur_f + 1, cur_g);
        st++;
    }
}

inline void solve(int l, int r) {
    if (r < l) return ;
    if (l == r) {
        modify(1, 0, n, l, f[l], g[l]);
        f[l] = -1, g[l] = 0, query(1, 0, n, l, f[l], g[l]);
        return ;
    }
    int pos = find(1, 0, n, l + 1, r);
    solve(l, pos - 1), solve(l, r, pos), solve(pos, r);
}

int main() {
    freopen("schooldays.in", "r", stdin);
    freopen("schooldays.out", "w", stdout);
    read_in();
    pre_work();
    build(1, 0, n);
    for (int i = 1; i <= n; ++i) f[i] = -1;
    g[0] = 1, solve(0, n);
    // for (int i = 1; i <= n; ++i) std::cout << f[i] << " " << g[i] << '\n';
    if (f[n] > -1) std::cout << f[n] << " " << g[n];
    else std::cout << "-1";
    return 0;
}

OJ Wrong Answer at Test 1

05-03

题目描述rn常见文本编辑器的一个功能是搜索,打开一段英文文字,根据一个给定的英文短语,可以搜索得到这个短语在文章中的位置,短语有可能重复出现。现请求出给定的短语在一段文字中出现的最后一个位置。文字中单词从1开始编号,所求的位置为短语第1个单词在这段文字中对应单词的编号。rn输入rn多行,每行以 # 为结束,第1行为一段英文文字(单词数、数字不多于500),其余行是待搜索的英文短语(单词数不多于10)。这里英文文字、英文短语只包含英文单词,这些单词以空格分隔。rn输出rn多行,每一行对应输入中给定的短语在文字中出现的最后一个位置,搜索不到时输出-1。rn样例输入rnSTOCKHOLM April 21 PRNewswire FirstCall Students from St Petersburg State University of IT Mechanics and Optics are crowned the 2009 ACM International Collegiate Programming Contest World Champions in the Stockholm Concert Hall where the Nobel Prizes are presented every year Sponsored by IBM the competition took place today at KTH the Royal Institute of Technology #rnSTOCKHOLM #rnSt Petersburg State University of IT Mechanics and Optics #rnWorld Champions #rnthe #rnNUPT #rn样例输出rn1rn8rn26rn51rn-1rn/* *************************************/rn#include rn#include rn#include rn#include rn#include rnusing namespace std;rnint main()rnrn string temp,sub;rn vector vs;rn vector v2;rn while(cin>>temp)rn rn if(temp[0]=='#') break;rn vs.push_back(temp);rn rn cin.get();rn temp="";rn while(getline(cin,sub))rn rn v2.clear();rn int len=sub.length();rn if(sub.length()==0) break;rn for(int i=0;i::iterator it;rn it=find_end(vs.begin(),vs.end(),v2.begin(),v2.end());rn if(it!=vs.end())rn rn cout<

Exception in thread "main" java.lang.NoClassDefFoundError: test (wrong name: db/test)

02-16

环境变量:rnCLASSPATH .;G:\j2sdk1.4.2_08\lib\dt.jar;G:\j2sdk1.4.2_08\lib\tools.jarrnJAVA_HOME G:\j2sdk1.4.2_08rnPATH G:\j2sdk1.4.2_08\binrnrnG:\MyWeb\Tomcat 5.0\webapps\test\src\Test\db\test.javarnpackage db; rnimport java.io.BufferedReader; rnimport java.io.File; rnimport java.io.FileReader; rnimport java.io.FileWriter; rnimport java.io.IOException; rnimport java.io.PrintWriter;rnrnpublic class test rn rn public static void main(String[] args) throws IOException rn rn test t = new test(); rn t.readAllFile(".//","Test.txt"); rn rn rn public void readAllFile(String filePath,String fileName) throws IOException rn rn FileReader fr = new FileReader(filePath+fileName); rn int count = fr.read(); rn while(count != -1) rn rn System.out.print((char)count); rn count = fr.read(); rn if(count == 13) rn rn fr.skip(1); rn rn rn fr.close(); rn rnrnException in thread "main" java.lang.NoClassDefFoundError: test (wrong name: db/rntest)rn at java.lang.ClassLoader.defineClass0(Native Method)rn at java.lang.ClassLoader.defineClass(Unknown Source)rn at java.security.SecureClassLoader.defineClass(Unknown Source)rn at java.net.URLClassLoader.defineClass(Unknown Source)rn at java.net.URLClassLoader.access$100(Unknown Source)rn at java.net.URLClassLoader$1.run(Unknown Source)rn at java.security.AccessController.doPrivileged(Native Method)rn at java.net.URLClassLoader.findClass(Unknown Source)rn at java.lang.ClassLoader.loadClass(Unknown Source)rn at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)rn at java.lang.ClassLoader.loadClass(Unknown Source)rn at java.lang.ClassLoader.loadClassInternal(Unknown Source)

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试