玲珑杯 Round #20

1161 - 康娜的数学课

Time Limit:1s Memory Limit:256MByte

Submissions:615Solved:221

DESCRIPTION

康娜上三年级了,老师要教她一些简单的算术。
Markdown
出题人:啊,为什么康娜这么萌
具体而言,老师总共给了康娜 nn 个问题,每个问题是这样的~
给你 x,l,rx,l,r[l,r][l,r] 以内的每一个数均可以使用任意次,请问你能不能让他们的和为 xx
这个题实在是太简单啦,于是康娜一眼就看出来了。
现在康娜把这题拿给了你,你能不能做出来呢?

INPUT
第一行一个整数 nn ,表示康娜询问的次数接下来 nn 行,每行三个整数 x,l,rx,l,r 意义如上。
OUTPUT
nn 行,如果能表示出则输出“QWQ” (不包括引号),如果不能表示出则输出"TAT"(不包括引号)
SAMPLE INPUT
15 2 3
SAMPLE OUTPUT
QWQ
HINT
n10000n≤10000 1x,l,r10181≤x,l,r≤1018

x一定要在[l,r]的整数倍的所有区间的并集里面。所以只需要枚举某一区间即可。一除法确定r,一模确定是否在区间内。

#include<bits/stdc++.h>
using namespace std;

int main(){
	int n;
	scanf("%lld",&n);
	long long x,l,r,t1,t2;
	while(n--){
		scanf("%lld%lld%lld",&x,&l,&r);
		t1=t2=0;
		t1=x/l; 
		t2=x%l;
		if(t2<=(r-l)*t1)puts("QWQ");
		else puts("TAT");	
	}
	return 0;
}


1157 - 造物主的戒律

Time Limit:20s Memory Limit:512MByte

Submissions:871Solved:109

DESCRIPTION






造物主的戒律,空气,变成数据结构!
于是空气变成了数据结构~
给你一个序列,每次查询区间中小于等于x的所有数字里面第k1k1小的值以及大于x的所有数字里面第k2k2小的值,如果不存在,输出-1
每次输出两个数,对于每个数如果不存在,则单独输出-1

INPUT
第一行两个数n,m第二行n个数表示序列a后面m行每行五个数l,r,x,k1,k2
OUTPUT
对于每个查询输出答案
SAMPLE INPUT
5 51 2 3 4 51 5 3 1 22 5 2 1 32 3 3 3 33 3 3 3 33 3 3 3 3
SAMPLE OUTPUT
1 52 5-1 -1-1 -1-1 -1
HINT
n,m<= 400000 ,0 <= a[i] <= 1000000000大家想知道这游戏叫什么吗叫liber7这个叫由乃的真的有毒。——来自另一个出题人。----------------------484觉得图多。我会告诉你我删了好多张了么。当然会,图好多还超级大。我都给它缩小了。——来自一个上题人

主席树询问区间k小值。对于大于x的第k小数,先查小于等于x的总共有几个,然后再查这个区间的第x+k小的数。

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 400010;
const int M = MAXN * 30;
int n,q,m,tot;
int a[MAXN], t[MAXN];
int T[MAXN], lson[M], rson[M], c[M];

void Init_hash()
{
    for(int i = 1; i <= n; i++)
        t[i] = a[i];
    sort(t+1,t+1+n);
    m = unique(t+1,t+1+n)-t-1;
}
int build(int l,int r)
{
    int root = tot++;
    c[root] = 0;
    if(l != r) {
        int mid = (l+r)>>1;
        lson[root] = build(l,mid);
        rson[root] = build(mid+1,r);
    }
    return root;
}

int update(int root,int pos,int val)
{
    int newroot = tot++, tmp = newroot;
    c[newroot] = c[root] + val;
    int l = 1, r = m;
    while(l < r) {
        int mid = (l+r)>>1;
        if(pos <= mid) {
            lson[newroot] = tot++;
            rson[newroot] = rson[root];
            newroot = lson[newroot];
            root = lson[root];
            r = mid;
        } else {
            rson[newroot] = tot++;
            lson[newroot] = lson[root];
            newroot = rson[newroot];
            root = rson[root];
            l = mid+1;
        }
        c[newroot] = c[root] + val;
    }
    return tmp;
}

int getsum(int left_root,int right_root,int x)
{
    if (x==0) return 0;
    int l = 1, r = m;
    int res = 0;
    while( l < r) {
        int mid=(l+r)>>1;
        if (mid<=x) {
            res+=c[lson[left_root]]-c[lson[right_root]];
            l=mid+1;
            left_root = rson[left_root];
            right_root = rson[right_root];
        } else {
            r=mid;
            left_root = lson[left_root];
            right_root = lson[right_root];
        }
    }
    return res;
}

int getkth(int left_root,int right_root,int k)
{
    int l = 1, r = m;
    while( l < r) {
        int mid = (l+r)>>1;
        if (c[left_root]-c[right_root] < k || k == 0) return -1;
        if (c[lson[left_root]]-c[lson[right_root]] >= k ) {
            r = mid;
            left_root = lson[left_root];
            right_root = lson[right_root];
        } else {
            l = mid + 1;
            k -= c[lson[left_root]] - c[lson[right_root]];
            left_root = rson[left_root];
            right_root = rson[right_root];
        }
    }
    return l;
}

namespace fastIO {
	#define BUF_SIZE 10000000
	//fread -> read
	bool IOerror = 0;
	inline char nc() {
		static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;
		if(p1 == pend) {
			p1 = buf;
			pend = buf + fread(buf, 1, BUF_SIZE, stdin);
			if(pend == p1) {
				IOerror = 1;
				return -1;
			}
		}
		return *p1++;
	}
	inline bool blank(char ch) {
		return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
	}
	inline void read(int &x) {
		char ch;
		while(blank(ch = nc()));
		if(IOerror)
			return;
		for(x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0');
	}
	#undef BUF_SIZE
};

int main()
{
    using namespace fastIO;
    read(n);read(q);
    tot = 0;
    for (int i = 1; i <= n; i++) {
        read(a[i]);
    }
    Init_hash();
    T[n+1] = build(1,m);
    for (int i = n; i ; i--) {
        int pos = lower_bound(t+1,t+1+m,a[i])-t;
        T[i] = update(T[i+1],pos,1);
    }
    while (q--) {
        int l,r,x,k1,k2;
        read(l);read(r);read(x);read(k1);read(k2);
        x=upper_bound(t+1,t+1+m,x)-t-1;
        int s=getsum(T[l],T[r+1],x);
        int a=getkth(T[l],T[r+1],k1);
        if (a > x) a=-1;
        if (a!=-1) a=t[a];
        int b=getkth(T[l],T[r+1],s + k2);
        if (b!=-1) b=t[b];
        printf("%d %d\n",a,b);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值