/************ A.An Olympian Math Problem ********************
题意:输入一个n,用S来表示S=1*1!+2*2!+······+(n-1)*(n-1)!,求S%n的结果
思路:打表找规律,列出前几项会发现ans=n-1,注意要开long long;
***************************************************************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
int t;
cin>>t;
while(t--){
ll n;
cin>>n;
cout<<n-1<<endl;
}
return 0;
}
/********************* B. The writing on the wall **************************
题意:有一个n*m的矩阵,里面有一些黑矩阵,问这个矩阵有多少个不带黑矩阵的矩阵
思路:把每个小的矩阵都当作一个子矩阵的一个右下角,暴力搜索每个充当右下角的子
矩阵可以存在多少个不含黑块的子矩阵,对于每一列,子矩阵个数应该是之前遍历的
最短的高度累加起来,然后对于每个小矩阵求和
一个三层的for循环遍历整个矩阵,时间复杂度为O(n*m*m);
对于第一层循环,遍历n列的元素,表示为i;
对于第一个二层循环,表示对于该列元素对于每个位置所能够达到的最大高度;
对于第二个二层循环,遍历这列元素的每一个点(即当做右下角的矩阵)
对于第三层循环,即表示这以这个小矩形为右下角,遍历剩下高度的所有情况之和
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(Map[i][j]) up[j]=i;
for(int j=1;j<=m;j++){
int Min=0x3f3f3f3f;
for(int k=j;k>0;k--){
Min=min(Min,i-up[k]);
ans+=(ll)Min;
}
}
}
****************************************************************************/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define met(a,b) memset(a,b,sizeof(a))
int Map[100005][105],up[105];
int main()
{
int t,cas=0;
scanf("%d",&t);
while(t--){
int n,m,k;
met(Map,0);
met(up,0);
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<k;i++){
int x,y;
scanf("%d%d",&x,&y);
Map[x][y]=1;
}
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
if(Map[i][j]) up[j]=i;
for(int j=1;j<=m;j++){
int Min=0x3f3f3f3f;
for(int k=j;k>0;k--){
Min=min(Min,i-up[k]);
ans+=(ll)Min;
}
}
}
printf("Case #%d: %lld\n",++cas,ans);
}
return 0;
}
/************************* E. AC Challenge *******************************
题意:有n道题目,每道题目对应有ai和bi两个分值,用time*ai+bi表示这个题目的
分值,其中time表示对应的第几个做这个题,每道题还有对应的前导题,即写这个
题目之前必须写的题目
思路:状压dp
1.这个题目首先是二进制优化,2^20大概1e6的样子,每个题目有m道前导题,可以
先利用0不需要做1需要做来记录这个题目是否可以做以及题目做过之后的状态
2.首先是输入以及预处理这个题可以做的前提条件,a b数组分别储存每个题目对应的
分数,d数组用一个n位的二进制表示做这道题目的前提条件,即d[i]+=1<<(x-1);
3.定义一个最大的可能情况 int now=(1<<n)-1;此时为可能情况的最大值
4.一个从0到now的循环,当(dp[i]==0&&i!=0)时,表示dp[i]没有被更新过,所以一定
不需要此状态,continue继续;
5.第二层循环遍历n道题目,如果可以做,把dp[i+(1<<j)]更新掉,此处为状态转移
方程,使得其步步最优dp[i+(1<<j)]=max(dp[i+(1<<j)],dp[i]+time(i)*a[j]+b[j]);
6.循环结束之后,求出dp数组中的最大值即为最优答案
****************************************************************************/
#include<bits/stdc++.h>
using namespace std;
#define maxn 1<<20
#define ll long long
ll dp[maxn];
int a[25],b[25],d[25];
int time(int x)
{
int cnt=0;
while(x){
x-=x&-x;
cnt++;
}
return cnt+1;
}
int main()
{
int n,m;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d%d",&a[i],&b[i],&m);
while(m--){
int x;
scanf("%d",&x);
d[i]+=1<<(x-1);
}
}
int now=(1<<n)-1;
for(int i=0;i<=now;i++){
if(dp[i]==0&&i!=0) continue;
for(int j=0;j<n;j++){
if((i&(1<<j))==0&&(i&d[j])==d[j]){
dp[i+(1<<j)]=max(dp[i+(1<<j)],dp[i]+time(i)*a[j]+b[j]);
}
}
}
ll ans=0;
for(int i=0;i<=now;i++){
ans=max(dp[i],ans);
}
printf("%lld\n",ans);
return 0;
}
/****************** J. Sum *****************************
题意:f(n)定义为n=a*b这样分解的式子,其中a和b不能包含平方因子。
当a!=b时n=a*b和n=b*a算两个式子。t组测试,求f(1)+f(2)+f(3)+···+f(n)
题解:有如下结论
1.若i是素数则f(i)=2;
2.若i的某个质数因子个数大于等于2,则f(i)=0;就是说当某个因子个数
大于等于2的时候,所分解的a*b或b*a必定有一个数含有平方因子,即f(i)=0;
3.若i=a*b且a和b不含相同因子,则f(i)=f(a)*(b);
4.若i的质因子x的个数为2,f(i)=f(i/(x*x))即为去掉平方因子个数
打表需要用欧拉筛法
**********************************************************/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e7+5;
bool vis[maxn]; //标记合数为true质数为false
int prime[maxn];//prime[0]存个数,后边存连续的质数
int ans[maxn];//结果
void solve()
{
ans[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]){
prime[++prime[0]]=i;
ans[i]=2;//情况1
}
for(int j=1;j<=prime[0]&&prime[j]*i<maxn;j++){
int x=prime[j]*i;
vis[x]=true;
if(i%prime[j]) ans[x]=ans[prime[j]]*ans[i];//情况3
else{
if(i%(prime[j]*prime[j])==0) ans[x]=0;//情况2
else ans[x]=ans[x/(prime[j]*prime[j])];//情况4
break;//欧拉筛法保证每个合数只被它的最小质因子筛去,因此要跳出
}
}
}
//前缀和
for(int i=1;i<maxn;i++){
ans[i]+=ans[i-1];
}
}
int main()
{
solve();
int t,n;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
printf("%d\n",ans[n]);
}
return 0;
}