【问题描述】
今天,新高一的OIer们第一次进入了机房。z老师想让他们喜欢上OI,于是给了他们每个人一个三角形。
这时候,小q秃发奇想,拿着手中的三角形,给大家出了一道题,请你帮助他们给小q一个正确的答案。
小q给了你两个整数m,n,请输出杨辉三角前n行的所有数的和模m的值。
如果你不知道杨辉三角是什么,请看样例解释。
【输入】
每个测试点有多组测试数据。
每个测试点第一行一个正整数T表示数据组数。
接下来T行每行两个正整数m,n表示一次询问。
【输出】
共T行,每行一个正整数,表示答案。
【输入输出样例】
3 5 6 7 2 2 998244353 | 3 3 1 |
#include<iostream>
#include<cstdio>
using namespace std;
int n,m;
int km(int a,int k)
{
int s=1;
while(k)
{
if(k&1)
s=1ll*s*a%m;
k>>=1;
a=1ll*a*a%m;
}
return s;
}
int rd()
{
int res=0;
char c=getchar();
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
res=(1ll*res*10+(c-'0'))%(m-1);
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
n=rd();
printf("%d\n",(km(2,n)-1+m)%m);
}
return 0;
}
T2、跳格子
【问题描述】
z老师不在,小q打开了u2!#u_f9f**30&8.io。——一个跳方格的小游戏。
小q坐到了靠里的一排,认为不会被发现,但他身后是反光的玻璃窗。
这是一个致命的失误。
现在z老师对这个游戏产生了兴趣,他准备尝试一下。
z老师有一个n*m的网格,每个格子上都写着一个数字。为方便描述,令左上角的网格为(1,1),右下角的网格为(n,m)。
z老师可以进入最下方第n行的任意一个网格,并按照以下规则进行游戏:
设z老师 第一次进入第i行的位置为 (i,ri);
如果z老师在 (i,ri),则他只能向左或向上跳。否则他可以向左,向右或向上跳。
z老师不能跳出网格,除非他在第1行,这代表结束整场游戏。
定义一局游戏的得分为所有z老师经过的格子上的数字之和。z老师想求出得分的最小值。
【输入】
第一行两个整数n,m,分别表示网格的行数和列数。
接下来n行,每行m个整数aij,表示 (i,j)上的数。
【输出】
一行一个整数,表示最小值。
【输入输出样例 1】
5 4 -21589 7315 -8753 28191 21541 1236 2038 11098 4408 8833 3280 -28896 19889 21948 -1769 25387 22241 888 -6112 28106 | -25590 |
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define LL_INF (long long)(0x3f3f3f3f3f3f3f3f)
#define N 1006
using namespace std;
int n,m;
int a[N][N];
long long f[N][N],sum[N][N],mx[N][N];
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
f[i][0]=LL_INF;
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
sum[i][j]=sum[i][j-1]+a[i][j];
mx[i][j]=max(sum[i][j],mx[i][j-1]);
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=min(f[i][j-1]+a[i][j],f[i-1][j]+sum[i][j]-mx[i][j-1]);
}
long long ans=LL_INF;
for(int j=1;j<=m;j++)
ans=min(ans,f[n][j]);
printf("%lld\n",ans);
return 0;
}
T3、亮度调节
【问题描述】
z老师很烦恼:偌大的机房空无一人,一排电脑屏幕却还亮着。
z老师更烦恼的是:这排电脑屏幕的亮度并不统一,有些很亮,有些很暗。
“这不好……至少要把亮度调整一下吧!”
z老师面前有一排 台电脑,每一台电脑都有一个用整数表示的亮度值 (可能为负数)。
在z老师走进机房时,他并不烦恼。
对于任意两台电脑,如果左边的亮度值大于右边的 (i﹤j,ai﹤aj)
,他就会获得 的烦恼值。
z老师可以进行的操作是,把一台电脑的亮度值修改为它的相反数。
他可以修改任意多次,以使得自己最终的烦恼值最小,而你需要求出这个最小值。
【样例输入】
第1行,一个整数n表示有n台电脑。
第2行共n个整数ai,表示从左往右第i台电脑的初始亮度值。
【样例输出】
一行一个整数,表示最小的烦恼值。
【样例1输入】
18
-1 -7 0 -2 -1 -7 5 1 1 6 -9 2 -7 9 0 -5 0 5
【样例1输出】
36
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e6+13;
inline int rd()
{
int x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=getchar();}
return y?x:-x;
}
int n;
int a[N];
struct Bit
{
int lowbit(int x)
{
return x&(-x);
}
int t[N],n;
void add(int pos,long long x)
{
for(;pos<=n;pos+=lowbit(pos))
t[pos]+=x;
}
int ask(int pos)
{
int ret=0;
for(;pos;pos-=lowbit(pos))
ret+=t[pos];
return ret;
}
}t1,t2;
int main()
{
n=rd();
t1.n=t2.n=100001;
for(int i=1;i<=n;i++)
a[i]=rd();
for(int i=1;i<=n;i++)
{
a[i]=abs(a[i])+1;
t2.add(a[i],1);
}
ll ans=0;
for(int i=1;i<=n;i++)
{
t2.add(a[i],-1);
ans+=min(t1.ask(a[i]-1),t2.ask(a[i]-1));
t1.add(a[i],1);
}
printf("%lld\n",ans);
return 0;
}