杭电多校总结2021-07-29

1001 Calculus

** Problem Description**
This summer, ZXyang became so tired when doing the problems of
Multi-University contests. So he decided to attend the Unified
National Graduate Entrance Examination. This day, he sees a problem of
series.

Let S(x) be a function with x as the independent variable. S(x) can be
represented by the formula as follow.

f(x)=∑i=1nfi(x)

S(x)=∑j=1xf(j)

fi(x) is a function with x as the independent variable. Furthermore.
fi(x) belongs to the function set F.

F={C,Cx,Csinx,Ccosx,Csinx,Ccosx,Cx,Cx}

C is a constant integer ranging from 0 to 109.

ZXyang wonders if S(x) is convergent. S(x) is convergent if and only
if limx→∞S(x)=c, where c is a constant.

Input
The first line of input contains a single integer t (1≤t≤104) — the
number of test cases.

The first and the only line of each test case contains a single string
s (1≤|s|≤100), indicating the formula of f(x). Fraction is presented
as a/b. Cx is presented as C^x. It’s guaranteed that the constant C
won’t be left out when C=1. f(x) consists of functions from F
connected with +.

Output
For each test case, print YES in one line if S(x) is a convergent sequence, or print NO in one line if not.

大意:
题意:给定几个级数,分别是C,Cx,Csinx,Ccosx,Csinx,Ccosx,Cx,Cx(C是常数),然后给出的式子时其中几个级数相加,问整个式子是否收敛。
注意到题中所给的所有函数均为发散。所以只需要检查是否所有的构成函数的系数均为 0 即可。

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

char s[1001],str[1001];
int t,len1,l2;
bool pd;
void solve()
{
	pd = false;
	cin>>s;
	pd = true;
	len1 = strlen(s);
	for(int i=0;i<len1;i++)
	{
		l2 = 0;
		while( s[i]!='+'&&i<len1 )
		{
			str[l2] = s[i];
			l2++;
			i++;
		}
		if( str[0]=='0' ) continue;
		
		if( str[l2-1]>='0' && str[l2-1]<='9' )
		{
			pd = false;
			continue;
		}
		
		if( l2>=5 )
		if( str[l2-4]=='s' || str[l2-4]=='c' )
		{
			pd = false;
			continue;
		}
		
		if( str[l2-1]=='x' )
		{
				pd = false;
		}
	}
	if( pd ) printf("YES\n");
	else printf("NO\n");
}

int main()
{
	freopen("in.txt","r",stdin);
	cin>>t;
		getchar();
	while( t-- ) solve();
	return 0;
}

1002 Kanade Loves Maze Designing

** Problem Description**
Kanade is designing a mini-game. It’s a puzzle game that orders
players to get out of a maze. Players should also collect as many
kinds of elements as they can to gain a better score.

For the easy mode, the maze can be described as a tree. There are n
crossings and n−1 undirected passages which make the n crossings
connected. The n crossings is numbered with integers from 1 to n.
Exactly one element is placed on each crossing. The kind of element
placed at crossing i is denoted by an integer ci in the range [1,n].

To evaluate the maze’s difficulty, Kanade wants to know how many kinds
of elements appear on p(u,v) for every two integers u,v∈[1,n]. p(u,v)
indicates the simple path from crossing u to crossing v in the maze.

Input
The first line of input contains one integer T (1≤T≤10), indicating
the number of test cases.

For each test case, the first line contains one integer n (2≤n≤2000),
indicating the number of crossings in the maze.

The second line contains n−1 integers p2,p3,…,pn (pi<i), indicating
that the i-th crossing is connected with the pi-th crossing by a
passage.

The third line contains n integers c1,c2,…,cn (1≤ci≤n), indicating
that the kind of element placed at crossing i is ci.

It is promised that for all test cases, ∑n≤5000.

Output
For each test case, output n lines. Each line contains two integers.
Let ai,j be the number of kinds of elements appear on p(i,j). Let
f(i,x)=∑j=1nai,jxj−1

Then for the i-th line, output f(i,19560929)mod(109+7) and
f(i,19560929)mod(109+9), space separated.

大意:
注意到允许一个O(n^2) 的算法,考虑用 ±1 法统计每种颜色即可。即,记 ci为颜色i的出现次数,r为从某点处开始 DFS,到点 得到的答案,进入该点时,给ci加一,如果这种颜色第一次出现,则给r加一,记录答案,退出该点时,如果给ci减一后这种颜色不会出现,则r减一。

#include <bits/stdc++.h>

using namespace std;

vector<int> g[2005];
int t, n;
int c[2005], p[2005], cnt[2005], bas1[2005], bas2[2005];
int sum;
const int mod1 = (int)1e9 + 7;
const int mod2 = (int)1e9 + 9;

void Init()
{
    bas1[0] = bas2[0] = 1;
    for(int i = 1; i <= 2000; ++i)
    {
        bas1[i] = 1ll * bas1[i - 1] * 19560929 % mod1;
        bas2[i] = 1ll * bas2[i - 1] * 19560929 % mod2;
    }
    return ;
}

void add(int x)
{
    if(!cnt[x]) sum++;
    ++cnt[x]; return ;
}

void del(int x)
{
    if(cnt[x] == 1) sum--;
    --cnt[x]; return ;
}

void dfs(int now, int la)
{
    add(c[now]); p[now] = sum;
    for(int i = 0; i < g[now].size(); ++i)
    {
        if(g[now][i] != la) dfs(g[now][i], now);
    }
    del(c[now]);
    return ;
}

void fadd1(int &x, int y) {x += y; if(x >= mod1) x -= mod1; return ; }
void fadd2(int &x, int y) {x += y; if(x >= mod2) x -= mod2; return ; }

int main()
{
    Init();
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        for(int i = 2, x; i <= n; ++i)
        {
            scanf("%d", &x);
            g[x].push_back(i); g[i].push_back(x);
        }
        for(int i = 1; i <= n; ++i) scanf("%d", &c[i]);
        for(int i = 1; i <= n; ++i)
        {
            dfs(i, -1);
            int ans1 = 0, ans2 = 0;
            for(int j = 1; j <= n; ++j)
            {
                fadd1(ans1, 1ll * p[j] * bas1[j - 1] % mod1);
                fadd2(ans2, 1ll * p[j] * bas2[j - 1] % mod2);
            }
            printf("%d %d\n", ans1, ans2);
        }
        for(int i = 1; i <= n; ++i) g[i].clear();
    }
    return 0;
}

1002 Kanade Loves Maze Designing

** Problem Description**
One day, a zombie came to the Lawn of the Dead, which can be seen as
an n×m grid. Initially, he stood on the top-left cell, which is (1,1).

Because the brain of the zombie was broken, he didn’t have a good
sense of direction. He could only move down from (i,j) to (i+1,j) or
right from (i,j) to (i,j+1) in one step.

There were k “lotato mines” on the grid. The i-th mine was at (xi,yi).
In case of being destroyed, he would never step into a cell containing
a “lotato mine”.

So how many cells could he possibly reach? (Including the starting
cell)

Input
The first line contains a single integer t (1≤t≤20), denoting the
number of test cases.

The first line of each test case contains three integers n,m,k
(2≤n,m,k≤105) — there was an n×m grid, and there were k “lotato
mines” on the grid.

Each of the following k lines contains 2 integers xi,yi
(1≤xi≤n,1≤yi≤m) — there was a “lotato mine” at (xi,yi). It’s
guaranteed that there was no “lotato mine” at (1,1) and no mines were
in the same cell.

It is guaranteed that ∑n≤7⋅105,∑m≤7⋅105.

Output
For each test case, output the number of cells he could possibly reach.

大意:
n×m 的网格
有 k kk 个土豆雷,坐标为 x i , y i 有一个僵尸在 ( 1 , 1 ) (1,1)(1,1)
一次移动可以向右 / 向下移动一格,但他不能走到土豆雷上,最后走到不能走为止。
他有多少个格子是能够走得到的?

考虑所有点的个数减去不能到达的点的个数,即为可以到达的点的个数。
根据题意,有地雷的地方是不可以到达的。由于僵尸只会向右和向下走,当某个点的左边和上方都不可
达时,该点不可达,并会对自己右边的点和下方的点造成影响。
由于空间很大但地雷数有限,可以从上往下逐行对每一行的地雷排序后进行处理。对每个地雷,找到从
自己的右上角点 开始的从左往右的连续不可达区域的范围,那么 这行的这个范围也
不可达。可以用线段树来实现区间查询和区间覆盖。每一行处理完后查询该行不可达的点数,累加后用
总点数减即得到答案。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值