SOJ4293 Product

统计大集合A中所有含奇数个元素的子集S中元素乘积的和!(我已经尽量说的很不饶了= =)

设ans1是A中所有奇数集元素积的和(要求的答案),ans2是A中所有偶数集元素积的和。

赋初值,令ans1=0,ans2=1(方便每次从空集变成单元素集的过程)

每个奇数集加入一个元素x后会变成偶数集,其元素积的和会乘以x,偶数集亦然。

这样每次加入x操作有:

ans1=ans1+ans2*x         (1)

ans2=ans2+ans1*x          (2)

删除操作时即是已知方程左边求右边,用(2)式乘以x减去(1)式,差除以(x*x-1),可以求出新的ans1,同理可求ans2,注意除法要用逆元。


#include <cstdio>
typedef long long ll;

int mod = 1000000007;
int n;
char cmd[10];
ll x,ans1[2],ans2[2];
bool flag;

ll inv(ll xx)
{
    ll res=1;
    int k=mod-2;
    while (k)
    {
        if (k&1) res=(res*xx)%mod;
        xx=(xx*xx)%mod;
        k>>=1;
    }
    return res;
}

int main()
{
    while (scanf("%d",&n)==1)
    {
        ans1[0]=0;
        ans2[0]=1;
        flag=0;
        while (n--)
        {
            flag^=1;
            scanf("%s %lld",cmd,&x);
            if (cmd[0]=='i')
            {
                ans1[flag]=(ans1[flag^1]+(ans2[flag^1]*x)%mod)%mod;
                ans2[flag]=(ans2[flag^1]+(ans1[flag^1]*x)%mod)%mod;
            }
            else
            {
                ans1[flag]=((((ans2[flag^1]*x)%mod-ans1[flag^1]+mod)%mod)*inv((x*x-1)%mod))%mod;
                ans2[flag]=((((((ans1[flag^1])*x)%mod)-ans2[flag^1]+mod)%mod)*inv((x*x-1)%mod))%mod;
            }
            printf("%lld\n",ans1[flag]);
        }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
详细设计: 1. 框图 ``` +----------------+ +------------------------+ | | | | | 用户操作界面 |<--------->| 服务器处理 | | | | | +----------------+ +------------------------+ ``` 2. 程序实现 (1)添加学生信息 ``` void add_student_info(char* file_name, char* student_id, char* student_name, float student_score) { FILE* fp = fopen(file_name, "a"); fprintf(fp, "%s\t%s\t%.2f\n", student_id, student_name, student_score); fclose(fp); } ``` (2)修改学生信息 ``` void modify_student_info(char* file_name, char* student_id, char* student_name, float student_score) { FILE* fp = fopen(file_name, "r"); FILE* tmp_fp = fopen("tmp.txt", "w"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); if (strcmp(id, student_id) == 0) { fprintf(tmp_fp, "%s\t%s\t%.2f\n", student_id, student_name, student_score); found = 1; } else { fprintf(tmp_fp, "%s", buf); } } fclose(fp); fclose(tmp_fp); if (found) { remove(file_name); rename("tmp.txt", file_name); } else { remove("tmp.txt"); } } ``` (3)删除学生信息 ``` void delete_student_info(char* file_name, char* student_id) { FILE* fp = fopen(file_name, "r"); FILE* tmp_fp = fopen("tmp.txt", "w"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10]; sscanf(buf, "%s", id); if (strcmp(id, student_id) == 0) { found = 1; } else { fprintf(tmp_fp, "%s", buf); } } fclose(fp); fclose(tmp_fp); if (found) { remove(file_name); rename("tmp.txt", file_name); } else { remove("tmp.txt"); } } ``` (4)查询学生信息 ``` void query_student_info(char* file_name, char* student_id) { FILE* fp = fopen(file_name, "r"); char buf[1024]; int found = 0; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); if (strcmp(id, student_id) == 0) { printf("%s\t%s\t%.2f\n", id, name, score); found = 1; break; } } fclose(fp); if (!found) { printf("Student info not found!\n"); } } ``` (5)显示所有学生信息 ``` void display_all_student_info(char* file_name) { FILE* fp = fopen(file_name, "r"); char buf[1024]; while (fgets(buf, sizeof(buf), fp) != NULL) { char id[10], name[20]; float score; sscanf(buf, "%s\t%s\t%f", id, name, &score); printf("%s\t%s\t%.2f\n", id, name, score); } fclose(fp); } ``` 3. 核心步骤图 (1)添加学生信息 ![add_student_info](https://i.imgur.com/0xZ8JYf.png) (2)修改学生信息 ![modify_student_info](https://i.imgur.com/8fO8mY0.png) (3)删除学生信息 ![delete_student_info](https://i.imgur.com/FXiw3xq.png) (4)查询学生信息 ![query_student_info](https://i.imgur.com/1RUK2gX.png) (5)显示所有学生信息 ![display_all_student_info](https://i.imgur.com/SOJ8LhL.png)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值