版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lfhase/article/details/81157619
比赛(题目)链接:https://www.nowcoder.com/acm/contest/140#question
A
签到题,每个点只会影响后面1步和k步的点,注意不要重复两次k就好了
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAXN = 100005;
const int MOD = 1e9+7;
long long DP_1[MAXN];
long long DP_2[MAXN];
long long DP[MAXN];
long long STEP;
int main()
{
int Q;
while(scanf("%d%lld",&Q,&STEP)!=EOF)
{
memset(DP_1,0,sizeof(DP_1));
memset(DP_2,0,sizeof(DP_2));
//for(int i=1;i<MAXN;++i) DP[i] = 1;
DP_1[0] = 1;
for(int i=0;i<MAXN;++i)
{
if(i+STEP<MAXN)
{
DP_2[STEP+i] = (DP_2[STEP+i]+DP_1[i])%MOD;
}
if(i+1<MAXN)
{
DP_1[i+1] = (DP_1[i+1]+DP_1[i]+DP_2[i])%MOD;
}
}
/* for(int i=1;i<MAXN;++i)
cout<<(DP_1[i]+DP_2[i])<<" ";
cout<<endl;*/
DP[0] = 0;
for(int i=1;i<MAXN;++i)
{
DP[i] = (DP[i-1]+DP_1[i]+DP_2[i])%MOD;
/*if(i<=100)
cout<<DP[i]<<" ";*/
}
while(Q--)
{
long long res = 0;
int l, r;
scanf("%d%d",&l,&r);
res = (DP[r]-DP[l-1])%MOD;
if(res<0) res+=MOD;
printf("%lld\n",res);
}
}
return 0;
}
D
签到题,贪心地取所有递增连续子序列最后两值相减即可。
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int MAXN = 100005;
const int MOD = 1e9+7;
int N;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>N;
long long profit = 0;
long long times = 0;
long long cur = -1;
long long curnum;
long long lastnum=-1;
for(int i=1;i<=N;++i)
{
scanf("%lld",&curnum);
if((lastnum!=-1&&cur==-1&&lastnum<curnum))
{
cur = lastnum;
}
else if(lastnum!=-1&&cur!=-1&&curnum<lastnum)
{
profit += lastnum-cur;
times+=2;
cur = -1;
}
lastnum = curnum;
}
if(cur!=-1&&lastnum>cur) profit+=lastnum-cur, times+=2;
printf("%lld %lld\n",profit,times);
}
return 0;
}
H
树形DP
设置两个数组:
DP [ i, j ] :表示树上前i个点选择j条链的最大值
SLink [ i, j ] : 表示树上前i个点选择j条链和一条包含i的直链(i为端点到叶子)的最大值
对于每一个子树,它对结果的贡献可以是:
1) None;
2)1,2,3条路径;
3) 一条直链+0,1,2,3条路径;
合并时按上述情况分类讨论即可,注意在存在直链的子树合并时,需要减1。
AC代码如下:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
const int MAXN = 400005;
const int MOD = 1e9+7;
const int INF = 1e9+7;
int N;
int weight[MAXN];
vector<int> mapp[MAXN];
long long DP[MAXN][5];
long long SLink[MAXN][5];
void rua(int u, int fa=0)
{
long long maxn[5][5], curmaxn[5][5], submaxn[5][5];
memset(maxn,0,sizeof(maxn));
memset(curmaxn,0,sizeof(curmaxn));
memset(submaxn,0,sizeof(submaxn));
for(int e:mapp[u])
{
if(e!=fa)
{
rua(e,u);
for(int i=0;i<=3;++i) submaxn[i][0]=DP[e][i], submaxn[i][1]=SLink[e][i];
for(int x1=0;x1<=3;++x1)
for(int x2=0;x2+x1<=3;++x2)
for(int sy1=0;sy1<=2;++sy1)
for(int sy2=0;sy2+sy1<=3;++sy2)
maxn[x1+x2][sy1+sy2] = max(maxn[x1+x2][sy1+sy2],curmaxn[x1][sy1]+submaxn[x2][sy2]);
memcpy(curmaxn,maxn,sizeof(maxn));
}
}
for(int i=0;i<=3;++i) DP[u][i] = max(DP[u][i],maxn[i][0]);
for(int i=1;i<=3;++i) DP[u][i] = max(DP[u][i],maxn[i-1][1]+weight[u]);
for(int i=1;i<=3;++i) DP[u][i] = max(DP[u][i],maxn[i-1][2]+weight[u]);
for(int i=0;i<=3;++i) SLink[u][i] = max(SLink[u][i],maxn[i][1]+weight[u]);
}
int main()
{
//freopen("output.txt","w+",stdout);
int u, v;
scanf("%d",&N);
for(int i=1;i<=N;++i) scanf("%d",weight+i);
for(int i=1;i<N;++i)
{
scanf("%d%d",&u,&v);
mapp[u].push_back(v);
mapp[v].push_back(u);
}
rua(1,0);
printf("%lld",DP[1][3]);
return 0;
}
I
找规律?规律就是n为偶数时能通过的车为2n,n为奇数时能通过的车是2n-1
摧毁格子时对应行列减一,注意奇数情况下对中心行列的处理即可。
AC代码如下:
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
const int MAXN = 100005;
const int MOD = 1e9+7;
const int INF = 1e9+7;
int N, M;
int cordx[MAXN], cordy[MAXN];
int main()
{
//freopen("output.txt","w+",stdout);
while(scanf("%d%d",&N,&M)!=EOF)
{
int res = N*2-(N%2);
memset(cordx,0,sizeof(cordx));
memset(cordy,0,sizeof(cordy));
int x, y;
/* for(int i=1;i<=N;++i)
cout<<cordx[i]<<" ";
cout<<endl;
for(int j=1;j<=N;++j)
cout<<cordy[j]<<" ";
cout<<endl;*/
for(int i=1; i<=M; ++i)
{
scanf("%d%d",&x,&y);
if(!cordx[x])
{
res --;
cordx[x] = 1;
}
if(!cordy[y])
{
res--;
cordy[y] = 1;
}
}
if(cordx[(N+1)/2]==cordy[(N+1)/2]&&cordy[(N+1)/2]==1) res++;
/*for(int i=1;i<=N;++i)
cout<<cordx[i]<<" ";
cout<<endl;
for(int j=1;j<=N;++j)
cout<<cordy[j]<<" ";
cout<<endl;*/
printf("%d\n",res);
}
return 0;
}
J
二维树状数组
考虑到每种肥料只会对对应种类的植物有作用,所以按植物/肥料种类进行分类判断
对每种植物,对农场矩阵施加非该种植物的化肥,
然后对该种植物每个点做一次前缀和判断,如果是0则无影响,如果是1则有影响。
AC代码如下:(事实上不用IO加速也能过【tao
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
using namespace std;
#define FSIO ios::sync_with_stdio(0);cin.tie(0);
#define DEBUG(a) cout<<"DEBUG: "<<(a)<<endl;
#define R register
namespace fastIO {
#define BUF_SIZE 100005
#define OUT_SIZE 100005
#define ll long long
//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;
}
//{printf("IO error!\n");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch) {
return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t';
}
inline void read(int &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc());
if (IOerror)return;
if (ch == '-')sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())x = x * 10 + ch - '0';
if (sign)x = -x;
}
inline void read(ll &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc());
if (IOerror)return;
if (ch == '-')sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())x = x * 10 + ch - '0';
if (sign)x = -x;
}
inline void read(double &x) {
bool sign = 0;
char ch = nc();
x = 0;
for (; blank(ch); ch = nc());
if (IOerror)return;
if (ch == '-')sign = 1, ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())x = x * 10 + ch - '0';
if (ch == '.') {
double tmp = 1;
ch = nc();
for (; ch >= '0' && ch <= '9'; ch = nc())tmp /= 10.0, x += tmp * (ch - '0');
}
if (sign)x = -x;
}
inline void read(char *s) {
char ch = nc();
for (; blank(ch); ch = nc());
if (IOerror)return;
for (; !blank(ch) && !IOerror; ch = nc()) * s++ = ch;
*s = 0;
}
inline void read(char &c) {
for (c = nc(); blank(c); c = nc());
if (IOerror) {
c = -1;
return;
}
}
//getchar->read
inline void read1(int &x) {
char ch;
int bo = 0;
x = 0;
for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())if (ch == '-')bo = 1;
for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar());
if (bo)x = -x;
}
inline void read1(ll &x) {
char ch;
int bo = 0;
x = 0;
for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())if (ch == '-')bo = 1;
for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar());
if (bo)x = -x;
}
inline void read1(double &x) {
char ch;
int bo = 0;
x = 0;
for (ch = getchar(); ch < '0' || ch > '9'; ch = getchar())if (ch == '-')bo = 1;
for (; ch >= '0' && ch <= '9'; x = x * 10 + ch - '0', ch = getchar());
if (ch == '.') {
double tmp = 1;
for (ch = getchar(); ch >= '0' && ch <= '9'; tmp /= 10.0, x += tmp * (ch - '0'), ch = getchar());
}
if (bo)x = -x;
}
inline void read1(char *s) {
char ch = getchar();
for (; blank(ch); ch = getchar());
for (; !blank(ch); ch = getchar()) * s++ = ch;
*s = 0;
}
inline void read1(char &c) {
for (c = getchar(); blank(c); c = getchar());
}
//scanf->read
inline void read2(int &x) {
scanf("%d", &x);
}
inline void read2(ll &x) {
#ifdef _WIN32
scanf("%I64d", &x);
#else
#ifdef __linux
scanf("%lld", &x);
#else
puts("error:can recognize the system!");
#endif
#endif
}
//fwrite->write
struct Ostream_fwrite {
char *buf, *p1, *pend;
Ostream_fwrite() {
buf = new char[BUF_SIZE];
p1 = buf;
pend = buf + BUF_SIZE;
}
void out(char ch) {
if (p1 == pend) {
fwrite(buf, 1, BUF_SIZE, stdout);
p1 = buf;
}
*p1++ = ch;
}
void print(int x) {
static char s[15], *s1;
s1 = s;
if (!x)*s1++ = '0';
if (x < 0)out('-'), x = -x;
while(x)*s1++ = x % 10 + '0', x /= 10;
while(s1-- != s)out(*s1);
}
void println(int x) {
static char s[15], *s1;
s1 = s;
if (!x)*s1++ = '0';
if (x < 0)out('-'), x = -x;
while(x)*s1++ = x % 10 + '0', x /= 10;
while(s1-- != s)out(*s1);
out('\n');
}
void print(ll x) {
static char s[25], *s1;
s1 = s;
if (!x)*s1++ = '0';
if (x < 0)out('-'), x = -x;
while(x)*s1++ = x % 10 + '0', x /= 10;
while(s1-- != s)out(*s1);
}
void println(ll x) {
static char s[25], *s1;
s1 = s;
if (!x)*s1++ = '0';
if (x < 0)out('-'), x = -x;
while(x)*s1++ = x % 10 + '0', x /= 10;
while(s1-- != s)out(*s1);
out('\n');
}
void print(double x, int y) {
static ll mul[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,
1000000000, 10000000000LL, 100000000000LL, 1000000000000LL, 10000000000000LL,
100000000000000LL, 1000000000000000LL, 10000000000000000LL, 100000000000000000LL
};
if (x < -1e-12)out('-'), x = -x;
x *= mul[y];
ll x1 = (ll)floor(x);
if (x - floor(x) >= 0.5)++x1;
ll x2 = x1 / mul[y], x3 = x1 - x2 * mul[y];
print(x2);
if (y > 0) {
out('.');
for (size_t i = 1; i < y && x3 * mul[i] < mul[y]; out('0'), ++i);
print(x3);
}
}
void println(double x, int y) {
print(x, y);
out('\n');
}
void print(char *s) {
while (*s)out(*s++);
}
void println(char *s) {
while (*s)out(*s++);
out('\n');
}
void flush() {
if (p1 != buf) {
fwrite(buf, 1, p1 - buf, stdout);
p1 = buf;
}
}
~Ostream_fwrite() {
flush();
}
} Ostream;
inline void print(int x) {
Ostream.print(x);
}
inline void println(int x) {
Ostream.println(x);
}
inline void print(char x) {
Ostream.out(x);
}
inline void println(char x) {
Ostream.out(x);
Ostream.out('\n');
}
inline void print(ll x) {
Ostream.print(x);
}
inline void println(ll x) {
Ostream.println(x);
}
inline void print(double x, int y) {
Ostream.print(x, y);
}
inline void println(double x, int y) {
Ostream.println(x, y);
}
inline void print(char *s) {
Ostream.print(s);
}
inline void println(char *s) {
Ostream.println(s);
}
inline void println() {
Ostream.out('\n');
}
inline void flush() {
Ostream.flush();
}
//puts->write
char Out[OUT_SIZE], *o = Out;
inline void print1(int x) {
static char buf[15];
char *p1 = buf;
if (!x)*p1++ = '0';
if (x < 0)*o++ = '-', x = -x;
while(x)*p1++ = x % 10 + '0', x /= 10;
while(p1-- != buf)*o++ = *p1;
}
inline void println1(int x) {
print1(x);
*o++ = '\n';
}
inline void print1(ll x) {
static char buf[25];
char *p1 = buf;
if (!x)*p1++ = '0';
if (x < 0)*o++ = '-', x = -x;
while(x)*p1++ = x % 10 + '0', x /= 10;
while(p1-- != buf)*o++ = *p1;
}
inline void println1(ll x) {
print1(x);
*o++ = '\n';
}
inline void print1(char c) {
*o++ = c;
}
inline void println1(char c) {
*o++ = c;
*o++ = '\n';
}
inline void print1(char *s) {
while (*s)*o++ = *s++;
}
inline void println1(char *s) {
print1(s);
*o++ = '\n';
}
inline void println1() {
*o++ = '\n';
}
inline void flush1() {
if (o != Out) {
if (*(o - 1) == '\n')*--o = 0;
puts(Out);
}
}
struct puts_write {
~puts_write() {
flush1();
}
} _puts;
inline void print2(int x) {
printf("%d", x);
}
inline void println2(int x) {
printf("%d\n", x);
}
inline void print2(char x) {
printf("%c", x);
}
inline void println2(char x) {
printf("%c\n", x);
}
inline void print2(ll x) {
#ifdef _WIN32
printf("%I64d", x);
#else
#ifdef __linux
printf("%lld", x);
#else
puts("error:can recognize the system!");
#endif
#endif
}
inline void println2(ll x) {
print2(x);
printf("\n");
}
inline void println2() {
printf("\n");
}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace fastIO;
const int MAXN = 1000005;
const int MOD = 1e9+7;
const int INF = 1e9+7;
int N, M;
// 2-d BIT
vector<int> data[MAXN];
void Add(int x, int y, int z) {
for (int i = x; i <= N; i += i & -i)
for (int j = y; j <= M; j += j & -j)
data[i][j] += z;
}
int Sum(int x, int y) {
int ans = 0;
for (int i = x; i; i -= i & -i)
for (int j = y; j; j -= j & -j)
ans += data[i][j];
return ans;
}
// end of 2-d BIT
vector<pair<int,int> > plants[MAXN];
vector<pair<pair<int,int>,pair<int,int>>> fertilizer[MAXN];
int main()
{
//freopen("output.txt","w+",stdout);
int T;
//scanf("%d%d%d",&N,&M,&T);
read(N);
read(M);
read(T);
for(int i=1; i<=N+1; ++i)
for(int j=1; j<=M+1; ++j)
data[i].push_back(0);
int plantype;
for(int i=1; i<=N; ++i)
for(int j=1; j<=M; ++j)
{
//scanf("%d",&plantype);
read(plantype);
plants[plantype].push_back({i,j});
}
int x1, y1, x2, y2, ftype;
for(int i=1;i<=T;++i)
{
//scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&ftype);
read(x1); read(y1); read(x2); read(y2); read(ftype);
fertilizer[ftype].push_back({{x1,y1},{x2,y2}});
Add(x1,y1,1);
Add(x2+1,y1,-1);
Add(x1,y2+1,-1);
Add(x2+1,y2+1,1);
}
int res = 0;
for(int i=1;i<=N*M;++i)
{
for(int j=0;j<fertilizer[i].size();++j)
{
Add(fertilizer[i][j].first.first,fertilizer[i][j].first.second,-1);
Add(fertilizer[i][j].second.first+1,fertilizer[i][j].first.second,1);
Add(fertilizer[i][j].first.first,fertilizer[i][j].second.second+1,1);
Add(fertilizer[i][j].second.first+1,fertilizer[i][j].second.second+1,-1);
}
for(int j=0;j<plants[i].size();++j)
if(Sum(plants[i][j].first,plants[i][j].second))
res++;
for(int j=0;j<fertilizer[i].size();++j)
{
Add(fertilizer[i][j].first.first,fertilizer[i][j].first.second,1);
Add(fertilizer[i][j].second.first+1,fertilizer[i][j].first.second,-1);
Add(fertilizer[i][j].first.first,fertilizer[i][j].second.second+1,-1);
Add(fertilizer[i][j].second.first+1,fertilizer[i][j].second.second+1,1);
}
}
//printf("%d\n",res);
println(res);
return 0;
}