目录
- 2019.10.9 题解报告
- 时间安排:
- 答题情况:
- 题目解析:
- 代码实现:
2019.10.9 题解报告
又是没有题解的 一次考试= =
时间安排:
T1: 9:50~11:00 T2: 9:00~9:45 T3: 8:20~9:00
- T1 神题不可写, 先去看T3, 发现一种通过建图实现的 的 70分思路,
暴力敲完去看T2 - T2 仔细瞅了一眼觉得是个zz题 , 调和级数一搞复杂度就很低,
考场上写了 线段树 , 被卡到40, 换了st表 变成80 - 最后搞T1 , 一开始没思路决定手推样例打表 ,
手玩多组数据后发现了规律
- T1 神题不可写, 先去看T3, 发现一种通过建图实现的 的 70分思路,
答题情况:
- T1: 70 T2:40 T3:0
题目解析:
T1:
可以发现 , 每次加水时 加的水量,
在保证过多导致不平衡的情况下 越多越优
对于第一次 加入的 水数 , 不能过多导致 数量=l时 不平衡,
则可以发现 , 第一次最优添加 l/2(整除) 的水
则对于 第二次添水 , 也要维持平衡 ,
则最多 添加 l - (l/2)(整除) 的水
之后 每次添水 , 都应该向水量较少的 杯子中添加
并且 为了保持 两水杯平衡 ,
一次最多添加 2 的水
则可以得到规律
T2:
80%数据:
根据调和级数,
枚举序列的 所有子序列, 复杂度较低- 题目所求子序列长度 >=d , 枚举子序列时 从 d+1开始枚举即可
对每一个 长度为d的 区间,求和
维护每一个 长度>d 的区间内, 最大的 长度为d的 区间的和
可以使用线段树 或st表由于 题目要求 静态区间最值 , 所以st表更优
对于线段树 因为不需要进行修改,所以只需要建树,查询即可可以快乐枚举 长度>d 的序列,
其最优的和 = 序列和 - 最大的 长度为d的 区间的和
T3:
大毒瘤数据结构
图上建线段树 再在线段树上修改并统计信息
代码实现:
T1:
- 考场代码:
//
/*
By:Luckyblock
*/
#include
#include
#define int long long
//=============================================================
int l,r;
//=============================================================
inline int read()
{
int s=1, w=0; char ch=getchar();
for(; !isdigit(ch);ch=getchar()) if(ch=='-') s =-1;
for(; isdigit(ch);ch=getchar()) w = w*10+ch-'0';
return s*w;
}
//=============================================================
signed main()
{
freopen("lock.in","r",stdin);
freopen("lock.out","w",stdout);
l = read(), r = read();
if(l == r) {printf("%d",(l==1||l==2)?1:2); return 0;}
printf("%lld",(r-l-2)/2+2);
/*
if(l<=1 && r<=1) {printf("0"); return 0;}
if(l<=2 && r<=2) {printf("1"); return 0;}
if(l == r) {printf("2"); return 0;}
ans[1][3] = 2;
ans[1][4] = 2;
ans[1][5] = 3;
ans[2][3] = 2;
ans[2][4] = 2;
ans[2][5] = 2;
ans[3][4] = 1;
ans[3][5] = 1;
ans[4][5] = 1;
printf("%d",ans[l][r]);
/*
double l1 = l*1.0, l2 = l1, r1 = r*1.0, r2 = r1;//l2,r2剩余
double le = 0, ri = 0;
le += (l1+1)/2, r2 -= (l1+1)/2, l2 -= (l1+1)/2;
if(le - 1 <= 0) {printf("1"); return 0;}
if(le - 1 )
*/
}
- 正解:
#include
#include
#include
#include
#include
#include
#include
#include
//#pragma GCC optimize(2)
#define int long long
#define MAXN 1000000
#define INF 1e9 + 7
using namespace std;
inline int read()
{
int x = 0, f = 1; char c = getchar();
while(c > '9' || c < '0'){ if (c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9'){ x = x * 10 + (c ^ 48); c = getchar(); }
return f * x;
}
signed main()
{
freopen("lock.in", "r", stdin);
freopen("lock.out", "w", stdout);
int l = read(), r = read();
if (r <= 1) puts("0");
else if (r <= 2) puts("1");
else if (r == l) puts("2");
else
{
if (r - l <= 1) r++;
if (l == 0) r--;
cout << (r - l) / 2 + 1;
}
return 0;
}
T2:
- 考场代码:
#include
#include
#include
#define max(a,b) (a>b?a:b)
#define int long long
const int MARX = 1e6+10;
//=============================================================
int n,p,d,ans=d , sum[MARX];
int MAX[MARX][20];
int lg[MARX];
//=============================================================
inline int read()
{
int s=1, w=0; char ch=getchar();
for(; !isdigit(ch);ch=getchar()) if(ch=='-') s =-1;
for(; isdigit(ch);ch=getchar()) w = w*10+ch-'0';
return s*w;
}
void build()
{
/*
for(int i=1;i<=MARX;i++)//预处理log函数
lg[i]=lg[i-1]+(1<
- 正解:
#include
#define ll long long
#define pb push_back
#define mk make_pair
#define rint register int
using namespace std;
inline ll read(){ll w=1,s=0;char ch=getchar();while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}return w*s;}
ll Sum[2000010];
ll tmp[2000010];
ll Max[2000010],pos[2000100];
int A[2000010];
ll n,p,d;
int main()
{
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
n=read(),p=read(),d=read();
for(rint i=1;i<=n;++i)
{
A[i]=read();Sum[i]=Sum[i-1]+A[i];
}
for(rint i=1;i<=d-1;++i) tmp[i]=Sum[i];
for(rint i=d;i<=n;++i)
{
tmp[i]=Sum[i]-Sum[i-d];
}
// if(n<=d)
// {
// cout<Max[tail]) tail--;
Max[++tail]=tmp[rp];
pos[tail]=rp;
}
}
else
{ ll tt=-1e18;
if(head<=tail) tt=max(tt,Max[head]);
tt=max(tt,tmp[rp+1]);
if(Sum[rp+1]-Sum[l-1]-tt<=p)
{
rp++;
while(head<=tail&&tmp[rp]>Max[tail]) tail--;
Max[++tail]=tmp[rp];
pos[tail]=rp;
}
else break;
}
}
ans=max(ans,rp-l+1);
}cout<
T3:
- 考场代码:
//
/*
By:Luckyblock
*/
#include
#include
#include
#define int long long
const int MARX = 1e5+10;
const int INF = 2e9+7;
//=============================================================
struct edge
{
int u,v,ne;
bool use;
}e[MARX<<2];
int n,k,num,ans , w[MARX],head[MARX];
//=============================================================
inline int read()
{
int s=1, w=0; char ch=getchar();
for(; !isdigit(ch);ch=getchar()) if(ch=='-') s =-1;
for(; isdigit(ch);ch=getchar()) w = w*10+ch-'0';
return s*w;
}
void add(int u,int v)//建图
{
e[++num].u = u, e[num].v = v;
e[num].ne = head[u], head[u] = num;
}
int lower_search(int value)//找到小于 value的最后一个位置
{
int pos;
for(int l=0,r=n+1; l<=r;)
{
int mid = (l+r) >> 1;
if(w[mid] >= value) r = mid-1;
else pos = mid,l = mid+1;
}
return pos;
}
int upper_search(int value)//找到大于value的第一个位置
{
int pos;
for(int l=0,r=n+1; l<=r;)
{
int mid = (l+r) >> 1;
if(w[mid] > value) pos = mid,r = mid-1;
else l = mid+1;
}
return pos;
}
//=============================================================
signed main()
{
freopen("fight.in","r",stdin);
freopen("fight.out","w",stdout);
n = read(), k = read(); w[n+1] = INF;
if(k == 0) {printf("0"); return 0;}
for(int i=1; i<=n; i++) w[i] = read();
std:: sort(w+1, w+n+1);
for(int i=n; i>=1; i--)
for(int j = 1; w[j] < w[i]; j++)
{
add(i,j); e[num].use = 1;
add(j,i);
}
while(k--)
{
int l = read(), r = read();
int le = lower_search(l)+1, ri = upper_search(r)-1;
for(int i=le; i<=ri; i++)
for(int j=head[i]; j; j=e[j].ne)
if(e[j].use == 1)
if(e[j].v >= le && e[j].v <= ri)
e[j].use = 0, e[(j%2?j+1:j-1)].use=1;
}
for(int u=1; u<=n; u++)
{
for(int i=head[u]; i; i=e[i].ne)
if(e[i].use && e[i].v > u)
for(int j=head[e[i].v]; j; j=e[j].ne)
if(e[j].use && e[j].v > e[j].u)
for(int k=head[e[j].v]; k; k=e[k].ne)
if(e[k].use && e[k].v == u)
ans++;
}
printf("%lld",ans);
}
/*
4 0
1 1 1 2
*/
- 正解:
#include
#define ll long long
#define pb push_back
#define mk make_pair
#define rint register int
//#define int ll
using namespace std;
inline int read(){int w=1,s=0;char ch=getchar();while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}while(isdigit(ch)){s=s*10+ch-'0';ch=getchar();}return w*s;}
typedef pair pa;
vector vec[200010];
int n,m;ll A[500010];
ll tot=0,q[500010];
ll Sum[500010],tag[500010],du[500100];
inline void pushdown(int now,int l,int r)
{
if(tag[now])
{ int mid=(l+r)>>1;
tag[now<<1]^=1;
tag[now<<1|1]^=1;
Sum[now<<1]=(mid-l+1)-Sum[now<<1];
Sum[now<<1|1]=(r-mid)-Sum[now<<1|1];
tag[now]=0;
}
}
inline void Modify(int now,int l,int r,int x,int y)
{
// cout<>1;
if(x<=mid) Modify(now<<1,l,mid,x,y);
if(y>mid) Modify(now<<1|1,mid+1,r,x,y);
Sum[now]=Sum[now<<1]+Sum[now<<1|1];
}
inline ll Query(int now,int l,int r,int x,int y)
{ if(x>y) return 0;
if(x<=l&&r<=y)
{
return Sum[now];
}pushdown(now,l,r);
int mid=(l+r)>>1;
ll res=0;
if(x<=mid) res=Query(now<<1,l,mid,x,y);
if(y>mid) res+=Query(now<<1|1,mid+1,r,x,y);
Sum[now]=Sum[now<<1]+Sum[now<<1|1];
return res;
}
inline void Solve()
{
for(rint i=1;i<=n;++i)
{
if(i!=1)
{
Modify(1,1,n,i-1,i-1);
}
int sz=vec[i].size();
for(rint j=0;j=y) continue;
vec[x].pb(mk(x,y));
vec[y+1].pb(mk(x,y));
}
Solve();
return 0;
}