zoukankan      html  css  js  c++  java
  • Day1 考试

    考试

    T1

    给定 (a), (b), (c)
    (a^b mod c)
    1.2 输入格式
    一行,空格隔开的三个数字,分别表示 (a); (b); (c)
    1.3 输出格式
    一个数字,表示答案。
    1.4 样例输入
    2 3 3
    1.5 样例输出

    2

    1.6 数据规模及约定
    对于 30% 的数据, 1 ≤ (a); (b); (c)(10^6)
    对于 60% 的数据, 1 ≤ (a); (b); (c)(10^9)
    对于 100% 的数据, 1 ≤ (a; b; c)(10^{15})

    显然快速幂搞定,但是(a,b)(long long)范围,所以再来个龟速乘

    一点补充:

    如果我们要读高精度且有知道mod,我们可以边读边取模.

    (鸣谢毒瘤Water_lift)

    (Code)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int inf=2147483647;
    inline ll read()
    {
    	char ch=getchar();
        ll x=0;bool f=0;//然鹅我这里看着1e15写成了int(甚至不知道自己为什么一共三个数要用快读)
        while(ch<'0'||ch>'9')
        {
        	if(ch=='-') f=1;
        	ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		x=(x<<3)+(x<<1)+(ch^48);
    		ch=getchar();
    	}
    	return f?-x:x;
    }
    ll a,b,c;
    ll mul(ll x,ll y)
    {
    	ll r=0;
    	while(y)
    	{
    		if(y&1) r=(r+x)%c;
    		x=x*2%c;
    		y>>=1;
    	}
    	return r;
    }
    ll ksm()
    {
    	ll r=1;
    	while(b)
    	{
    		if(b&1) r=mul(r,a);
    		a=mul(a,a);
    		b>>=1;
    	}
    	return r;
    }
    int main()
    {
    	freopen("nine.in","r",stdin);
    	freopen("nine.out","w",stdout);
        a=read();b=read();c=read();
        printf("%lld",ksm());
    }
    
    T2

    2.1 问题描述
    给定长度为 (n) 的序列 (a_i)
    求满足以下要求的 (i; j) 数对的数量。
    (i<j)
    (a_i > a_j)
    ((a_i + a_j)equiv0mod3)
    2.2 输入格式
    第一行一个整数 (n)
    接下来一行,空格隔开的 (n) 个整数,表示 (a_i)
    2.3 输出格式
    输出包含一个数字,表示答案。
    2.4 样例输入
    5
    2 3 1 1 4
    2.5 样例输出
    2
    2.6 样例解释
    (1,3), (1,4) 满足要求

    2.7 数据规模及约定
    对于前 30% 的数据,$ n$ ≤ 2000。
    对于前 60% 的数据, (n) ≤ 4 × (10^4)
    对于前 100% 的数据, 1 ≤ (n)(10^5), 0 ≤ (a_i)(10^6)

    显然前两个条件是逆序对

    归并做法:

    归并排序可求逆序对个数

    处理条件3:若((a+b) mod 3=0),则(a mod 3+b mod 3=0),所以我们可以每次都维护一个后缀和,计算(mod 3=0)(mod 3=1)(mod 3=2)的数的个数

    (Code (from std))

    #include<cstdio
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    typedef long long LL;
    
    int n;
    int a[100005];
    int b[100005];
    int sum[100005][3];
    
    LL ans;
    
    void merge_sort(int l,int r){
        if(l==r) return;
        int mid=(l+r)/2;
        merge_sort(l,mid);
        merge_sort(mid+1,r);
        for(int i=l;i<=r;i++) b[i]=a[i];
        for(int i=mid;i>=l;i--){
            if(i<mid) for(int j=0;j<3;j++) sum[i][j] = sum[i+1][j];//由于是从mid直接覆盖过来所以不用memset
            sum[i][b[i]%3]++;
        }
        int i = l;
        int j = mid+1;
        int k = l;
    
        while(i<=mid && j<=r){
            if(b[i]<=b[j]){
                a[k++]=b[i];
                i++;
            }else{
                // solve
                ans += sum[i][(3-b[j]%3)%3];
                a[k++]=b[j];
                j++;
            }
        }
        while(i<=mid) a[k++] = b[i],i++;
        while(j<=r) a[k++] = b[j],j++;//由于i已经到了mid,所以不需要再统计逆序对了
    }
    
    int main(){
    	
    	freopen("teen.in", "r", stdin);
    	freopen("teen.out", "w", stdout);
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        merge_sort(1,n);
        printf("%lld
    ",ans);
        return 0;
    }
    

    树状数组做法:

    可以开3棵树状数组,分别维护(mod 3=0,mod 3=1,mod 3=2)的数。因为树状数组我不会求后缀和,所以树状数组里记录的值(d)(10^6+1)减原值,这样就要找使得((d+a) mod 3=1)(a)

    (Code)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int inf=2147483647;
    inline ll read()
    {
    	char ch=getchar();
        int x=0;bool f=0;
        while(ch<'0'||ch>'9')
        {
        	if(ch=='-') f=1;
        	ch=getchar();
    	}
    	while(ch>='0'&&ch<='9')
    	{
    		x=(x<<3)+(x<<1)+(ch^48);
    		ch=getchar();
    	}
    	return f?-x:x;
    }
    int n,a[100009],b[1000009][3];
    ll ans;
    int hv[1000009];
    const int all=(int)1e6+1;
    void add(int d)
    {
    	int md=d%3;hv[d]++;
    	while(md<0) md=(md+3)%3;
    	for(;d<=all;d+=(d&(-d)))
    	 b[d][md]++;
    }
    ll sum(int d,int md)
    {
    	ll r=0,dd=d;
    	while(md<0) md=(md+3)%3;
    	for(;d;d-=(d&(-d)))
    	 r+=b[d][md];
    	if(dd%3==md&&hv[dd]) r-=hv[dd];
    	return r; 
    }
    int main()
    {
    	freopen("teen.in","r",stdin);
    	freopen("teen.out","w",stdout);
    	n=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read();
    	for(int i=1;i<=n;i++)
    	{
    		int d=all-a[i];
    		ans+=sum(d,(1-d+3)%3);
    	    add(d);
    	} 
    	printf("%lld",ans);
    }
    
    T3

    3.1 问题描述
    给定一个长度为 n 的序列 ai, 和一个数字 k。
    如果一个区间 a[l : r] 满足以下条件,称其为 (gamma) 区间。
    (l < r)
    (max_{l≤i≤r}a_i - min_{l≤i≤r}a_i ≤ k)
    询问所有 (gamma) 区间的数字和。因为这个值很大,所以输出答案模 (10^9 + 7)的余数就好了。
    因输入量较大,推荐使用以下函数进行读入。

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

    3.2 输入格式
    第一行空格隔开的两个整数 n; k 。
    接下来一行,空格隔开的 n 个整数,表示 ai。
    3.3 输出格式
    输出只有一个整数,表示答案。
    3.4 样例输入
    6 1
    2 3 1 1 1 4
    3.5 样例输出
    12
    3.6 样例解释
    共四个 (γ) 区间。
    a[1..2] = 2,3
    a[3..5] = 1,1,1
    a[3..4] = 1,1
    a[4..5] = 1,1
    3.7 数据规模及约定
    对于前 30% 的数据, n ≤ 103 。
    对于前 60% 的数据, n ≤ 105。
    对于前 100% 的数据, 1 ≤ n ≤ 1000000, 0 ≤ ai; k ≤ 109。

    先只考虑(gamma)区间的数量

    我们发现如果区间([l,r])是合法的,那么([l,r'],l<r'<r)一定是个合法区间,如果([l,r])不合法,那么([l,r''],r''>r)一定不合法。对于每个(l),我们想找一个最靠后的(r)

    所以我们可以在枚举左端点的同时二分右端点

    二分+(check):

    注意如果区间([l,n])是合法的,那么二分出来的右端点会是(n-1)而不是(n),所以要先判一遍。

    复杂度(O(nlogn))

    我们想想能不能(O(n))找到(γ)区间。

    我们枚举(l)每次(+1),那么新的(r)和原来的(r)肯定有联系。

    (l')为新的(l),(r')为新的(r),则([l',r])肯定是合法区间,那么(r')一定不会比(r)小,所以可以直接移动(r),每次都判断一下是否合法。

    这样移动(l,r)总体是(O(n))

    但是(check)还是(logn)的,所以怎样才能(O(1) check)?

    由于(l,r)都是不断往后移,不会往前,所以可以用单调队列。开两个单调队列分别维护(Max)(Min),(check)一次(O(1)),总复杂度(O(n))

    求数字和:
    第一个区间可以暴力求出来。

    考虑转移。

    (l->l+1,r)不变:减去(len imes a[l]),其中(len)是区间([l,r])的长度

    (l)不变,(r->r+1):加上(sum[r+1]-sum[l-1]),也就是加上区间([l,r+1])的区间和

    (Code) ((from std))

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    typedef long long LL;
    int n,k;
    int a[1000005];
    LL ans;
    const LL mod=1e9+7;
    
    struct dddl{
    	int q[1000005];
    	int h,t;
    	void push(int x){
    		while(h!=t && a[q[t-1]]>=a[x]) t--;
    		q[t++] = x;
    	}
    	void pop(int x){
    		if(q[h] == x) h++;
    	}
    	int ask(){
    		return a[q[h]];
    	}
    }mn;
    
    struct dddl2{
    	int q[1000005];
    	int h,t;
    	void push(int x){
    		while(h!=t && a[q[t-1]]<=a[x]) t--;
    		q[t++] = x;
    	}
    	void pop(int x){
    		if(q[h] == x) h++;
    	}
    	int ask(){
    		return a[q[h]];
    	}
    }mx;
    
    int main(){
    	
    	freopen("nineteen.in", "r", stdin);
    	freopen("nineteen.out", "w", stdout);
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    	int first = 1;
    	LL sum=0;
    	LL sum_suf=0;
    	for(int i=1;i<=n;i++){
    		mn.push(i);
    		mx.push(i);
    		sum = (sum+a[i])%mod;
    		sum_suf = ((sum_suf)%mod+a[i]*(i-first+1)%mod)%mod;
    		while(mx.ask() - mn.ask()>k){
    			mx.pop(first);
    			mn.pop(first);
    			sum_suf = (sum_suf-sum+mod)%mod;
    			sum = (sum-a[first]%mod+mod)%mod;
    			first++;
    		}
    		ans += sum_suf;
    		// printf("# %d %d %lld %lld
    ",first, i, sum, sum_suf);
    	}
    	for(int i=1;i<=n;i++) ans = (ans-a[i]%mod+mod)%mod;
    	cout<<ans<<endl;
    
    	return 0;
    }
    
  • 相关阅读:
    struts2文件下载的编写步骤(文件导出)和输入流转换的方法
    spring的applicationContext.xml配置SessionFactory抛异常
    引用第三方高德地图接口---使用js脚本进行开发地图定位的步骤
    登陆时不同浏览器获取session存在的相关疑问?
    统一的异常处理和自定义的全局异常处理器的配置使用
    国际化的工具类ognl utils
    oracle中decode的用法(例子)
    PLSQL连接本机oracle 11g 64 数据库的步骤
    处理oracle 报ORA-12505 信息:listener does not currently know of SID given in connect descriptor...
    spring容器的配置和springmvc的配置
  • 原文地址:https://www.cnblogs.com/lcez56jsy/p/12209800.html
Copyright © 2011-2022 走看看