2018.5.31//考试总结

六一儿童节的前一天,我们竟然考试了!竟然考试了!!竟然考试了!!!(虽然作者已不是儿童)
且这次考试作者可谓考的一塌糊涂…………,由于钟爱的线段树还没有人家的暴搜优秀,不仅赔了时间,还只拿了人家一般的分数。

先搬上这两题邪恶的线段树

阶乘数组(array.cpp)

题目描述

       给出长度为n的序列A1,A2,…,An。进行m次操作,有三种类型:

  1. 给出l,r,将区间[l,r]的Ai都加一。

  2. 给出l,r,询问区间[l,r]的Ai!的和,对10^9取模。

  3. 给出I,v,将Ai单点修改为v。

格式

       输入第一行两个数n,m,第二行n个数Ai

接下来m行,每行三个数,第一个数k,表示第几类操作,后面两个数如题所述。

输出:对于每个操作2输出解。

范围

      

Sample Input 0

5 7
1 1 1 1 1
2 1 5
1 1 5
2 1 5
1 1 3
2 1 5
3 1 15
2 1 5

Sample Output 0

5
10
22
674368016

 


 

 


二进制操作数组

 

题目描述

输入格式

输出格式

 

数据范围

      

Sample Input 0

6 6
8 9 1 13 9 3
1 4 5
2 6 9
1 3 7
2 7 7
1 6 1
2 11 13

Sample Output 0

45
19
21

 虽然知道排版不好看,作者以无力改变 (其实就是懒)
然后是作者的线段树

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

#define C getchar()
#define maxn 100010
#define rep(i,j,p)  for(int i=j;i<=p;i++)
#define ll long long

inline ll read()
{
 ll x=0;
 bool flag=true;
 char ch;
 for(;ch>'9'||ch<'0';ch=C)
 if(ch=='-')
 flag=false;
 for(;ch>='0'&&ch<='9';ch=C)
 x=(x<<3)+(x<<1)+(ch^48);
 return flag?x:-x;
}

ll n,m;
struct cutetree
{
	ll zhi;
	ll lazy;
}tree[4*maxn]={};
ll k1,k2,v;

ll xj(ll x)
{
	ll k=1;
	for(ll i=2;i<=x;i++)
	  k=k*i%1000000000;
	return k%1000000000;
}

void build(ll root,ll l,ll r)
{
	if(l==r)   
	{
	tree[root].zhi=read();
	if(tree[root].zhi>39)
	  tree[root].zhi=0;
	return;
	}
	ll mid=l+r>>1;
	build(root<<1,l,mid);
	build(root<<1|1,mid+1,r);
	tree[root].zhi=tree[root<<1].zhi+tree[root<<1|1].zhi;
}

void growl(ll root,ll l,ll r)
{
	if(l>k2||r<k1)
	   return;
	if(l==r)   
	{
	tree[root].zhi=v;
	return;
	}
	ll mid=l+r>>1;
	ll delta=tree[root].lazy;
	tree[root].lazy=0;
	tree[root*2+1].lazy+=delta;
	tree[root*2].lazy+=delta;
	tree[root*2+1].zhi+=delta;
	tree[root*2].zhi+=delta;
	growl(root<<1,l,mid);
	growl(root<<1|1,mid+1,r);
	tree[root].zhi=tree[root<<1].zhi+tree[root<<1|1].zhi;
}

ll getsum(ll root,ll l,ll r)
{
	ll ans=0;
	if(l>k2||r<k1)
	   return 0;
	if(l==r)   
	{
	ans=xj(tree[root].zhi);
	return ans;
	}
	ll mid=l+r>>1;
	ll delta=tree[root].lazy;
	tree[root].lazy=0;
	tree[root*2+1].lazy+=delta;
	tree[root*2].lazy+=delta;
	tree[root*2+1].zhi+=delta;
	tree[root*2].zhi+=delta;
	return getsum(root*2,l,mid)+getsum(root*2+1,mid+1,r);
}

void add(ll root,ll l,ll r)
{
	if(l>k2||r<k1)
	   return;
	if(l>=k1&&r<=k2)   
	{
	tree[root].zhi++;
	if(tree[root].zhi>39)
	tree[root].zhi=0;
	tree[root].lazy++;
	if(tree[root].lazy>39)
	tree[root].lazy=0;
	return;
	}
	ll mid=l+r>>1;
	ll delta=tree[root].lazy;
	tree[root].lazy=0;
	tree[root*2+1].lazy+=delta;
	tree[root*2].lazy+=delta;
	tree[root*2+1].zhi+=delta;
	tree[root*2].zhi+=delta;
	add(root<<1,l,mid);
	add(root<<1|1,mid+1,r);
	tree[root].zhi=tree[root<<1].zhi+tree[root<<1|1].zhi;
}

int  main()
{
	n=read();
	m=read();
	build(1,1,n);
	for(ll i=1;i<=m;i++)
	{
		ll k=read();
		if(k==1)
		{
			k1=read();
			k2=read();
			add(1,1,n);
		}
		if(k==2)
		{
			k1=read();
			k2=read();
			ll h=getsum(1,1,n);
			cout<<h<<endl;
		}
		if(k==3)
		{
			k1=read();
			k2=k1;
			v=read();
			if(v>39)
			v=0;
			growl(1,1,n);
		}
	}
	return 0;
}
第二题
#include <bits/stdc++.h>
using namespace std;

#define C getchar()
#define maxn 10010
#define rep(i,j,p)  for(int i=j;i<=p;i++)

inline int read()
{
 int x=0;
 bool flag=true;
 char ch;
 for(;ch>'9'||ch<'0';ch=C)
 if(ch=='-')
 flag=false;
 for(;ch>='0'&&ch<='9';ch=C)
 x=(x<<3)+(x<<1)+(ch^48);
 return flag?x:-x;
}

int n,q;
int tree[maxn*4]={};
int k1,k2;

void build(int root,int l,int r)
{
	if(l==r)
	  {
	  tree[root]=read();
	  return;
	  }
	int mid=l+r>>1;
	build(root<<1,l,mid);
	build((root<<1)+1,mid+1,r);
	tree[root]=tree[root*2]+tree[root*2+1];
}

int add(int root,int l,int r,int x,int y)
{
	if(k1>r||k2<l)
	  return 0;
	if(l==r)
	  return tree[root]+x&y;
	int mid=l+r>>1;
	return add(root<<1,l,mid,x,y)+add((root<<1)+1,mid+1,r,x,y);
}

void growl(int root,int l,int r,int j)
{
	if(k1>r||k2<l)
	  return;
	if(l==r)
	 {
	  tree[root]=j;
	  return;
	 } 
	int mid=l+r>>1;
	growl(root<<1,l,mid,j);
	growl((root<<1)+1,mid+1,r,j);
	tree[root]=tree[root*2]+tree[root*2+1];
}

int main()
{
	n=read();
	q=read();
	build(1,1,n);
	for(int i=1;i<=q;i++)
	{
		int op=read();
		if(op==1)
		{
			k1=read();
			k2=k1;
			int v=read();
			growl(1,1,n,v);
		}
		if(op==2)
		{
			k1=1;
			k2=n;
			int ol=read();
			int ok=read();
			int h=add(1,1,n,ol,ok);
			printf("%d\n",h);
		}
	}
	return 0;
}
/*线段树 */ 

乍一看还满装逼的,但是并没有什么卵用(都不是正解)
其实第二题一开始的时候作者还想用树状数组做,但冥思苦想了好久之后发现实在是能力有限,做不出;

但其实这给作者最大的教训还不是这一点,而是有没有认真的审题,且硬是吧int的数据范围记成了2^31-1(不是亦或符,而是指数运算),导致了第二题阴沟里翻船,把已经到手的40分给扔了,实在可惜。
再来说说其它的题目

第一题是大水题,掠过
第二题

好大的Gcd(gcd.cpp)

题目描述

       有两个数组A,B,大小均为N。请在A中选择一个数xB中选择一个数y,使得gcd(x,y)最大;如果有多组数gcd相同,找出x+y最大的。

格式

       输入:第一行一个数n,第二行n个数表示Ai,第三行n个数表示Bi

       输出:输出gcd最大的那对数(gcd相同则和最大)的x+y的值。

范围

Sample Input 0

5
3 1 4 2 8
5 2 12 8 3

Sample Output 0

16

数论没学好系列,本来是一个很巧妙的题目,硬是做成了暴搜…………正解其实是开一个数组来存储最大公因数的数,然后通过倍数求解。
第三题

买买买(purchase.cpp)

题目描述

       蓝月商场有n件宝贝,每件宝贝有两个属性:价钱price和品牌brand。其中brand1-5之间某个整数。每件宝贝价钱两两不同。

       贪玩蓝月有Q个代言人,每个代言人拍完戏之后,希望能从蓝月商场免费顺走一样宝贝。但是每个代言人有自己的喜好,例如古天乐只喜欢品牌1,陈小春喜欢品牌1或品牌2,渣渣辉喜欢品牌35……具体来说,代言人会有d个喜欢的品牌(1 <= d <= 5),同时他最喜欢这些品牌中,价钱k便宜的宝贝。

       请你求出每个代言人最喜欢的宝贝的价钱是多少!如果不存在这件宝贝,请输出-1.

格式

       输入:第一行一个整数n,第二行n个整数描述每件宝贝的品牌,第三行n个数描述每件宝贝的价钱。第四行一个整数Q,接下来Q*3行,每3行描述一个代言人的信息。其中第一行一个整数d,第二行d个数表示喜欢的品牌,第三行一个数表示k

       输出:一共Q行,每行一个数。

范围:

      

Sample Input 0

3
1 1 2
1 3 2
3
1
1
2
2
1 2
2
1
3
1

Sample Output 0

3
2
 
 

-1


依然不会巧妙地方法,只好暴搜…………但其实正解很容易想到,就是一个二分答案,看来作者思考的敏捷度与深度还是不够,也没有足够的耐性,过早地放弃了很多分数。

第四题:干爆字符串 (被字符串干爆poi)


题目描述

       有两个仅包含小写字母的字符串x,y,长度分别为n,m。你需要修改x串中某些字符,是的新的x串和y串的最长公共子序列长度至少为k

       我们将’a’…’z’对应成0…25,修改两个字符付出的代价,为它们对应的数的xor值。比如说,将’a’修改成’z’代价为0 xor 25=25

       请问最少付出多少代价,使得新的x串和y串的LCS大于等于k

格式

       输入:第一行三个数n,m,k,第二行长度为n的字符串x,第三行长度为m的字符串y

       输出:最小花费,如果不能请输出-1

范围:

SampleInput 0

7 4 2

merging

pair

SampleOutput 0

3

完全没思路,听了正解之后依然不会;
综上所述:作者还是太菜了,太菜了,太菜了,太菜了,思考的深度与广度以及码代码的能力,还有自信心与耐心都急需提高

猜你喜欢

转载自blog.csdn.net/airno2/article/details/80529884